2017-01-11 10 views
0

Я использую услугу factory для получения некоторых данных, используя услугу $http. Проблема здесь, я не хочу делать запрос http каждый раз, я хочу сохранить эти данные где-нибудь и получить локальную копию, когда это необходимо. С этой целью я подумал о создании массива внутри этого factory и присвоить ему загруженные данные при первом вызове, а затем просто вернуть его, когда это необходимо, вместо того, чтобы снова загружать его с сервера. В моем случае, услуга http увольняется каждый раз. Как я могу это исправить? Я читал here, но это не отвечает на мой вопрос.Ограничить http-звонки с заводской службы

Это мой factory:

angular.module("app").factory("getDataService", ['$http', function ($http) { 
    var usersArray = []; 
    if (usersArray.length === 0) { 
     return { 
      getJsonData: function() { 
       return $http.get('https://api.myjson.com/bins/eznv3') 
        .success(function (data, status, headers, config) { 
         usersArray = data; 
         return data; 
        }) 
        .error(function (error, status, headers, config) { 
        }); 
      } 
     } 
    }else{ 
     return usersArray; 
    } 
}]); 

И это controller, который использует эту услугу:

angular.module("app").controller("ctrl", ["$scope", "getDataService", function ($scope, getDataService) { 

    angular.element(document).ready(function() { 
      getDataService.getJsonData().then(function (data) { 
       $scope.users = data.data; 
      }); 
    }); 
}]); 
+0

Что @ankit отвечал правильно. Другой способ - хранить данные в HTML sessionStorage при первом вызове & set isCacheFlag = true. Перед удалением сервера вы можете проверить, является ли флаг ложным, а затем ударить по серверу, чтобы выполнить ответ с сеанса или локального хранилища. –

+0

Спасибо за дополнение! Кстати, мы тоже создаем свой собственный код, но мы должны управлять им для каждого запроса, который мы делаем, если мы хотим кэшировать ответ всех запросов на получение. Но {cache: true} намного лучше, чем сложность кода. –

ответ

1

Вам не нужно кэшировать ответ $http.get вручную, сам angularJS обеспечивает способ для кэширования ответа. Попробуйте ниже код в функции getJsonData вашего завода:

getJsonData: function() { 
    return $http.get('https://api.myjson.com/bins/eznv3', {cache: true}) 
    .success(function (data, status, headers, config) { 
      return data; 
    }) 
    .error(function (error, status, headers, config) { 
    }); 
} 

Источник: https://docs.angularjs.org/api/ng/service/$http#get

Прочитайте вышеуказанный документ. Оттуда вы найдете конфигурации.

2

Вы можете использовать Локальное хранилище для этого, одно из лучших и простых способов.

LocalStorage.setItem('usersArray',data); устанавливает данные в локальном хранилище.

LocalStorage.getItem('usersArray'); извлекает данные из локального хранилища.

Вот это изменение вашего завода,

angular.module("app").factory("getDataService", ['$http', function ($http) { 
    var usersArray = LocalStorage.getItem('usersArray'); 
    if (usersArray.length === 0) { 
     return { 
      getJsonData: function() { 
       return $http.get('https://api.myjson.com/bins/eznv3', {cache: true}) 
        .success(function (data, status, headers, config) { 
         usersArray = data; 
         LocalStorage.setItem('usersArray',data); 
         return data; 
        }) 
        .error(function (error, status, headers, config) { 
        }); 
      } 
     } 
    }else{ 
     return LocalStorage.getItem('usersArray'); 
    } 
}]); 

Вашего контроллер,

angular.module("app").controller("ctrl", ["$scope", "getDataService", function ($scope, getDataService) { 

    var x = []; 

    angular.element(document).ready(function() { 
     if (x.length == 0) { 
      getDataService.getJsonData().then(function (data) { 
       x = data.data; 
       $scope.users = x; 
      }); 
     }else{ 
      console.log("local copy of data exists"); 
     } 
    }); 
}]); 

Преимущество LocalStorage:

  • с локальным хранилищем, веб-приложения могут хранить данные локально в браузере пользователя.
  • В отличие от файлов cookie, ограничение на хранение намного больше (не менее 5 МБ), и информация никогда не передается серверу.
+0

Вам не кажется, что ему нужно проверить, является ли местное хранилище нулевым или нет. Если его значение null делает ajax-вызов else, то обслуживать данные из локального хранилища –

+0

да хороший улов, @ Kgn-web, thnx. обновил ответ. – Sravan

+0

Я никогда не пробовал этот вариант, поэтому, хотя все добавляют это, я не добавлял, потому что не знаю, было ли это правильно. как вы сказали, я собираюсь добавить сейчас. thnx для этого. – Sravan

1

Несколько дней назад, я получил такие же требование и следующий код модуля я создал для же ...

'use strict'; 
(function() { 
    angular.module('httpService', []).service("api", ["$http", "dbService", function($http, dbService) { 
     /** 
     * <Pankaj Badukale> 
     *() 
     * request.url  => Url to request 
     * request.method => request method 
     * request.data  => request data 
     * request.mask  => This is custom object for out use 
     * 
     * @return() 
     */ 
     return function (request) { 
      var url   = (request != undefined && request.url != undefined) ? request.url : "./"; 
      var method  = (request != undefined && request.method != undefined) ? request.method : "GET"; 
      var rData  = (request != undefined && request.data != undefined) ? request.data : {}; 
      /** 
      * mask is CUSTOME object we add to request object 
      * Which is useful for keep track of each request as well interceptor execute 
      * 
      * IT HAS 
      * { 
      *  save  : true, //tell that save request response in session 
      *  fetch  : true, //check local data first, 
      *  fetchSource : tell about perticular source of data DEFAULT WILL BE sessionStorage 
      *     OPTIONS are session and local 
      * } strucutre FOR NOW may be it will better or enhance in future 
      * 
      * message property to set message in alert 
      * doExecute tell wheather you want to execute maskMan code for this request 
      * 
      * while saving and fetching data from local it uses URL of request as key 
      * maskMan is a factory which iterate your error response object and we can add different behaviours for maskMan 
      */ 
      var mask  = {}; 

      if(request != undefined && request.mask != undefined) { 
       mask = request.mask; 
      } 

      return dbService.http(request).then(function(data) { 
       console.log("Data fetched from local "+ request.url); 
       return data; 
      }, function(err) { 
       return $http({ 
        url: url, 
        method: method, 
        data: rData, 
        mask: mask, 
        header:{ 
          'content-type':'application/json' 
        } 
       }).then(function(response) { 
        return response.data; 
       },function(error) { 
        return error; 
       }); 
      }); 
     }; 
    }]).service('customHttpInterceptor', ["$q", "maskMan", function($q, maskMan) { 
     return { 
      //before send request to server 
      request: function(config) {     
        return config; 
      }, 
      //if any found in request object 
      requestError: function(rejection) { 
        return $q.reject(rejection); 
      }, 
      //on response come to web app 
      response: function(response) {    
       maskMan.responseIterator(response); 
       //you to return any thing as response from here 
       return response; 
      }, 
      //if there is error in response` 
      responseError: function(rejection) {     
       maskMan.statusIterator(rejection);    
       return $q.reject(rejection); 
      } 
     }; 
    }]).factory("maskMan", ["dbService", function(dbService) { 
     return { 
      /** 
      * statusIterator 
      * Iterate response object on error comes 
      */ 
      statusIterator: function(rejection) { 
       if(rejection.config.mask.doExecute == true) { 
        switch(rejection.status) { 
         case 404: this.notFound(rejection); 
          break; 
         default: this.dontKnow(rejection); 
        } 
       } 
      }, 
      /** 
      * notFound 
      * Function to defined logic for 404 error code scenario's 
      * Here we can defined generic as well specific request object conditions also 
      */ 
      notFound: function(rejection) { 
       var errMsg = rejection.config.mask.message || "Something wrong"; 

       alert(errMsg); 

       rejection.stopExecute = true;//stop further execute of code flag 
      }, 
      /** 
      * dontKnow 
      * For every error response this method goingt to envoke by default 
      */ 
      dontKnow: function(maskObject) { 
       console.log("Don't know what to do for "+maskObject.config.url); 
      }, 
      /** 
      * responseIterator 
      * Define logic to do after response come to browser 
      * 
      * @params JSON resp 
      */ 
      responseIterator: function(resp) { 
       //Logic to save data of response in session storage with mask command save 
       if(resp.config.mask !== undefined && resp.config.mask.save === true) { 
        var sdata = JSON.stringify(resp.data); 
        var skey = resp.config.url; 

        dbService.sinsert(skey, sdata); 
       }//END 
      } 
     }; 
    }]).service("dbService", ["$q", function($q) { 
     /** 
     * http 
     * Custom mirror promise to handle local storage options with http 
     * 
     * @params JSON request 
     */ 
     this.http = function(request) { 
      var self = this; 
      return $q(function(resolve, reject) { 
       if(request.mask != undefined && request.mask.fetch === true) { 
        var data = null; 

        if(request.mask.fetchSource == undefined || request.mask.fetchSource == "session") {//go for default sessionStorage 
         data = JSON.parse(self.sget(request.url)); 
        } else if(request.mask.fetchSource == "local") { 
         data = JSON.parse(self.get(request.url)); 
        } else { 
         reject("Fetch source is not defined."); 
        } 

        if(data != undefined && data != null) { 
         resolve(data); 
        } else { 
         reject("Data not saved in local "+request.url); 
        } 
       } else { 
        reject("Data not saved in local "+request.url); 
       } 
      }); 
     } 

     /** 
      * Add/Override data to local storage 
      * 
      * @params String key 
      * @params Array/Json data 
      * @params Function callback 
      * 
      * @return Boolean/Function 
      */ 
     this.insert = function(key, data, callback) {   
      localStorage.setItem(key, data); 

      if(callback != undefined) { 
       callback(); 
      } else { 
       return true; 
      } 
     } 

     /** 
      * Update data of local storage 
      * This function generally used to data which is already exist and need to update 
      * 
      * @params String key 
      * @params Array/Json data 
      * @params Function callback 
      * 
      * @return Boolean/Function 
      */ 
     this.update = function(key, data, callback) { 
      var self = this; 
      self.view(key, function(localData) {//callback function 
       if(localData != undefined && localData != null) { 
        //already some data exist on this key So need to update it 
        data = localData.push(data); 
       } 
       //just handover to insert 
       if(callback !== undefined) { 
        self.insert(key, data, callback); 
       } else { 
        return self.insert(key, data); 
       } 
      });   
     } 

     /** 
      * Remove data from local storage on basis of key 
      * 
      * @params String key 
      * @return Boolean 
      */ 
     this.remove = function(key, callback) { 
       localStorage.removeItem(key); 

       if(callback !== undefined) { 
        callback(); 
       } else { 
        return true; 
       } 
     } 

     /** 
      * Get key data of local storage 
      * @param String key 
      * 
      * @return Array data WHEN all data OR 
      * @return String data WHEN key value 
      */ 
     this.get = function(key, callback) { 
      var key = key || ""; 
      var data = []; 

      if(key == "") { 
       //get all data 
       for(var i in localStorage) { 
        data.push(JSON.parse(localStorage[i])); 
       } 
      } else { 
       //get one key data 
       data = localStorage.getItem(key); 
      } 

      if(callback != undefined) { 
       callback(data); 
      } else { 
       return data; 
      } 
     } 

     /** 
      * sinsert 
      * Add/Override data to session storage 
      * 
      * @params String key 
      * @params Array/Json data 
      * @params Function callback 
      * 
      * @return Boolean/Function 
      */ 
     this.sinsert = function(key, data, callback) { 
      var key = this.encode(key); 

      sessionStorage.setItem(key, data); 

      if(callback != undefined) { 
       callback(); 
      } else { 
       return true; 
      } 
     } 

     /** 
      * supdate 
      * Update data of session storage 
      * This function generally used to data which is already exist and need to update 
      * 
      * @params String key 
      * @params Array/Json data 
      * @params Function callback 
      * 
      * @return Boolean/Function 
      */ 
     this.supdate = function(key, data, callback) { 
      var self = this; 
      self.view(key, function(localData) {//callback function 
       if(localData != undefined && localData != null) { 
        //already some data exist on this key So need to update it 
        data = localData.push(data); 
       } 
       //just handover to insert 
       if(callback !== undefined) { 
        self.insert(key, data, callback); 
       } else { 
        return self.insert(key, data); 
       } 
      });   
     } 

     /** 
      * sremove 
      * Remove data from session storage on basis of key 
      * 
      * @params String key 
      * @return Boolean 
      */ 
     this.sremove = function(key, callback) { 
       var key = this.encode(key); 

       sessionStorage.removeItem(key); 

       if(callback !== undefined) { 
        callback(); 
       } else { 
        return true; 
       } 
     } 

     /** 
      * get 
      * Get key data of session storage 
      * @param String key 
      * 
      * @return Array data WHEN all data OR 
      * @return String data WHEN key value 
      */ 
     this.sget = function(key, callback) { 
      var key = key || ""; 
      var data = []; 

      if(key == "") { 
       //get all data 
       for(var i in sessionStorage) { 
        data.push(JSON.parse(sessionStorage[i])); 
       } 
      } else { 
       //get one key data 
       key = this.encode(key); 

       data = sessionStorage.getItem(key); 
      } 

      if(callback != undefined) { 
       callback(data); 
      } else { 
       return data; 
      } 
     } 

     /** 
      * encode 
      * encode give string using javascript 
      * 
      * @param String str 
      * @return String 
      */   
     this.encode = function(str) { 
      return btoa(str); 
     } 

     /** 
      * decode 
      * decode give string using javascript 
      * 
      * @param String str 
      * @return String 
      */     
     this.decode = function(str) { 
      return atob(str); 
     } 

     return this; 

    }]).config(['$httpProvider', function($httpProvider) { 
      $httpProvider.interceptors.push('customHttpInterceptor'); 
    }]); 
})(); 

Как пользоваться ::

Включите этот модуль в вас проект ....

Затем используйте «httpService» всегда для http-запросов всего для вызовов API ...

Нам необходимо передать объект конфигурации для этой службы говорят о API вызова и что с ним делать .... Вы можете найти подробную информацию о конфигурации в самом коде ...

Так как использовать контроллер. .

module.controller('nameofController', ['httpService', function(httpService) { 
    httpService({ 
     url: 'Your API url', 
     method: 'GET', 
     mask: { 
        save  : true, //tell that save request response in session 
        fetch  : true, //check local data first before next fetch, 
        fetchSource : tell about perticular source of data DEFAULT WILL BE sessionStorage OPTIONS are session and local 
      } 
    }).then(function(data) { 
     // promise is all same as $http 
     console.log(data); 
    }); 
}]); 

Надеется, что это поможет ... Вы можете пойти с очень простым решением, а просто отметить

{cache: true}

... Но это решение полностью настроенный и под все элементы управления

Оригинальный код, который используется в производстве находится gist