2017-01-11 2 views
0

Ich benutze einen factory Service, um einige Daten zu holen, die den Service $http verwenden. Das Problem hier, ich möchte nicht eine http Anfrage jedes Mal machen, möchte ich diese Daten irgendwo speichern und eine lokale Kopie davon erhalten, wenn sie benötigt werden. Zu diesem Zweck dachte ich, ein Array innerhalb dieser factory zu erstellen und die geladenen Daten beim ersten Aufruf zuzuweisen, und dann nur bei Bedarf zurückgeben, anstatt es erneut vom Server zu laden. In meinem Fall wird der Dienst http jedes Mal ausgelöst. Wie kann ich das beheben? Ich lese here, aber das beantwortet meine Frage nicht.Beschränken Sie http Anrufe von einem Fabrikservice

Das ist mein 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; 
    } 
}]); 

Und das ist die controller, die diesen Dienst verwendet:

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

Was geschrieben @ankit korrekt ist. Eine andere Möglichkeit ist das Speichern der Daten in HTML sessionStorage beim ersten Aufruf & set isCacheFlag = true. Bevor Sie den Server treffen, können Sie überprüfen, ob die Flagge falsch ist und dann den Server drücken. Anderenfalls sollten Sie die Antwort von Session oder Local liefern. –

+0

Vielen Dank für die Ergänzung! Übrigens machen wir auch unseren eigenen Code, aber wir müssen ihn für jede Anfrage, die wir machen, verwalten, wenn wir die Antwort aller get-Anfragen zwischenspeichern wollen. Aber {cache: true} ist viel besser als die Code-Komplexität. –

Antwort

1

Sie müssen nicht manuell die Antwort von $http.get zwischenzuspeichern, AngularJS selbst bietet eine Möglichkeit, die Antwort zwischenspeichern. Versuchen Sie unter Code in Ihrer getJsonData Funktion Ihrer Fabrik:

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) { 
    }); 
} 

Quelle: https://docs.angularjs.org/api/ng/service/$http#get

Lesen Sie das oben genannte Dokument. Sie finden Konfigurationen von dort.

2

Sie können Local Storage dafür verwenden, eine der besten und einfachsten Möglichkeiten.

LocalStorage.setItem('usersArray',data); legt die Daten im lokalen Speicher fest.

LocalStorage.getItem('usersArray'); ruft die Daten aus dem lokalen Speicher ab. Hier

ist die Änderung Ihrer Fabrik,

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

Ihr Controller,

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

Vorteile von localstorage:

  • Mit lokalen Speicher, Web-Anwendungen können Daten speichern lokal im Browser des Benutzers.
  • Im Gegensatz zu Cookies ist das Speicherlimit weitaus größer (mindestens 5 MB) und Informationen werden niemals auf den Server übertragen.
+0

Glaubst du nicht, dass er überprüfen muss, ob der lokale Speicher null ist oder nicht? Wenn seine Null einen Ajax-Aufruf machen, sonst dienen die Daten aus dem lokalen Speicher –

+0

ja gut fangen, @ Kgn-Web, Thnx. aktualisierte die Antwort. – Sravan

+0

Ich habe diese Option nie ausprobiert, also fügt jeder hinzu, aber ich habe nichts hinzugefügt, weil ich nicht weiß, ob es korrekt war. Wie du das gesagt hast, werde ich jetzt hinzufügen. thnx dafür. – Sravan

1

Nur wenige Tage zurück, ich erhielt gleiche Art von Anforderung und finden Sie Code des Moduls i für denselben geschaffen hatte ...

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

Wie es benutzen ::

Fügen Sie dieses Modul in Ihrem Projekt ....

Dann verwenden Sie "httpService" immer für http Anfragen alle für API-Aufrufe ...

Wir brauchen Config-Objekt zu diesem Dienst zu übergeben sagen, über API-Aufruf und was damit tun soll .... Sie Details über config in Code finden sich ...

So wie in der Steuerung zu verwenden.

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

Hope this helfen ... Sie mit sehr einfache Lösung gehen kann, als auch zu markieren gerade

{cache: true}

... Aber diese Lösung ist vollständig angepasst und unter allen Kontrollen

Original-Code, der in der Produktion eingesetzt hat, ist bei gist

Verwandte Themen