2017-01-11 46 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中並設置isCacheFlag = true。在點擊服務器之前,您可以檢查該標誌是否爲false,然後點擊服務器,然後從服務器或本地服務器返回響應 –

+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'); 
    } 
}]); 

你的控制器的localStorage的

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"); 
     } 
    }); 
}]); 

優點:

  • 具有本地存儲,Web應用程序可以存儲數據本地在用戶的瀏覽器內。
  • 與Cookie不同,存儲限制要大得多(至少5MB),並且信息永遠不會傳輸到服務器。
+0

你不覺得他需要檢查本地存儲是否爲空。如果null爲ajax調用,否則從本地存儲中提供數據 –

+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'); 
    }]); 
})(); 

如何使用它::

包括此模塊在你的項目....

然後使用「HTTP服務」始終爲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

相關問題