Javascript AngularJS-如何缓存服务的ajax结果以在控制器中重用

Javascript AngularJS-如何缓存服务的ajax结果以在控制器中重用,javascript,jquery,angularjs,ajax,Javascript,Jquery,Angularjs,Ajax,建议我使用Angular服务,以便集中存储在控制器中的许多重复函数,因此我现在使用服务重写代码 一开始看起来很简单,但似乎找不到一个好的结构来获取ajax数据(仅一次),然后将其存储在我的服务中,以便我的控制器在需要时重用缓存的数据。目前,我不断收到错误信息,如:TypeError:无法读取未定义的的属性“sayHello” 我相信这是因为在控制器加载之前,通过我的服务获取ajax数据有延迟。我不太确定如何优化这个。有谁有更好的结构吗 服务: app.service('MyService',函数

建议我使用Angular服务,以便集中存储在控制器中的许多重复函数,因此我现在使用服务重写代码

一开始看起来很简单,但似乎找不到一个好的结构来获取ajax数据(仅一次),然后将其存储在我的服务中,以便我的控制器在需要时重用缓存的数据。目前,我不断收到错误信息,如:
TypeError:无法读取未定义的
的属性“sayHello”

我相信这是因为在控制器加载之前,通过我的服务获取ajax数据有延迟。我不太确定如何优化这个。有谁有更好的结构吗

服务: app.service('MyService',函数($http){

控制器:

app.controller('AppController', function (MyService, $scope) {

    $scope.configurations = null;
    $scope.configurations = function() { MyService.sayHello() }; 

});
app.controller('AppController', ['MyService', '$scope', function(MyService, $scope) {

 // do your stuff here

}]);

好的,仔细想想,您似乎没有正确使用依赖项数组表示法。请将代码更改为:

app.service('MyService', ['$http', function ($http) {
  // do your stuff here
}]);
对于控制器:

app.controller('AppController', function (MyService, $scope) {

    $scope.configurations = null;
    $scope.configurations = function() { MyService.sayHello() }; 

});
app.controller('AppController', ['MyService', '$scope', function(MyService, $scope) {

 // do your stuff here

}]);

好的,仔细想想,您似乎没有正确使用依赖项数组表示法。请将代码更改为:

app.service('MyService', ['$http', function ($http) {
  // do your stuff here
}]);
对于控制器:

app.controller('AppController', function (MyService, $scope) {

    $scope.configurations = null;
    $scope.configurations = function() { MyService.sayHello() }; 

});
app.controller('AppController', ['MyService', '$scope', function(MyService, $scope) {

 // do your stuff here

}]);

我建议您使用另一种方式来声明服务:

 app.factory("MyService", function($http){
   var configurations = {};

 $http({
        method: 'GET',  
        url: 'AJAX PATH',
        headers: { "Accept": "application/json;odata=verbose;charset=utf-8"} 
    }).then(function(data){

         configurations = data;
         configurations.data_result_1 =                                              configurations.data_result_1.split("\r\n");
         configurations.data_result_2 = configurations.data_result_2.split("\r\n");

    });
 return {

  getConfigurations: function(){
    return configurations;
    }
}

在控制器中,您可以使用$watch,然后当配置对象更改时,您可以获取以下信息:

 .controller("YourCtrl", function($scope,MyService){
   var vm = this;
   vm.configurations = {};

     $scope.$watchCollection(function () { return MyService.getConfigurations()},function(newValue){
  vm.configurations = newValue;
});

我建议您使用另一种方式来声明服务:

 app.factory("MyService", function($http){
   var configurations = {};

 $http({
        method: 'GET',  
        url: 'AJAX PATH',
        headers: { "Accept": "application/json;odata=verbose;charset=utf-8"} 
    }).then(function(data){

         configurations = data;
         configurations.data_result_1 =                                              configurations.data_result_1.split("\r\n");
         configurations.data_result_2 = configurations.data_result_2.split("\r\n");

    });
 return {

  getConfigurations: function(){
    return configurations;
    }
}

在控制器中,您可以使用$watch,然后当配置对象更改时,您可以获取以下信息:

 .controller("YourCtrl", function($scope,MyService){
   var vm = this;
   vm.configurations = {};

     $scope.$watchCollection(function () { return MyService.getConfigurations()},function(newValue){
  vm.configurations = newValue;
});

完全同意Bri4n在工厂的存储配置。不同意控制器,因为你说你不想观看,但只加载一次数据

但是您$http已经返回了一个承诺,正如Brian所说,这很好(这里$q是无用的,您可以从注入中删除它)。我刚刚包装了http调用函数,公开的函数只是检查配置是否已经加载。如果是,只返回配置,否则加载它,然后返回它

 app.factory("MyService", function($http,$q){
   var configurations = {};

 function loadConfig(){
 $http({
        method: 'GET',  
        url: 'AJAX PATH',
        headers: { "Accept": "application/json;odata=verbose;charset=utf-8"} 
    }).then(function(data){

         configurations = data;
         configurations.data_result_1 =                                              configurations.data_result_1.split("\r\n");
         configurations.data_result_2 = configurations.data_result_2.split("\r\n");

    });
} 返回{

  getConfigurations: function(){
    If( !!configurations ){
        return configurations;
    }
    //Else loadConfig.then return configurations 
    }
}

在您的控制器中,您只需获取配置,而无需知道它是否已加载

 .controller("YourCtrl", function(MyService){
   var vm = this;
   // If configurations already loaded return config, else load configurations and return configurations.
   vm.configurations = MyService.getConfigurations();

我在手机上写代码,因此我的代码不完美,无法正确编写。

完全同意Bri4n关于工厂存储配置的意见。不同意控制器,因为你说你不想观看,但只加载一次数据

但是您$http已经返回了一个承诺,正如Brian所说,这很好(这里$q是无用的,您可以从注入中删除它)。我刚刚包装了http调用函数,公开的函数只是检查配置是否已经加载。如果是,只返回配置,否则加载它,然后返回它

 app.factory("MyService", function($http,$q){
   var configurations = {};

 function loadConfig(){
 $http({
        method: 'GET',  
        url: 'AJAX PATH',
        headers: { "Accept": "application/json;odata=verbose;charset=utf-8"} 
    }).then(function(data){

         configurations = data;
         configurations.data_result_1 =                                              configurations.data_result_1.split("\r\n");
         configurations.data_result_2 = configurations.data_result_2.split("\r\n");

    });
} 返回{

  getConfigurations: function(){
    If( !!configurations ){
        return configurations;
    }
    //Else loadConfig.then return configurations 
    }
}

在您的控制器中,您只需获取配置,而无需知道它是否已加载

 .controller("YourCtrl", function(MyService){
   var vm = this;
   // If configurations already loaded return config, else load configurations and return configurations.
   vm.configurations = MyService.getConfigurations();

我在手机上写代码,因此我的代码不完美,无法正确编写。

代码结构中存在问题,但不足以导致该错误。您确定这是引发错误的版本吗?也许可以考虑使用CacheFactory进行响应。或者在http请求中指定缓存,这样您就可以再次调用它,然后接收缓存结果,而不是发出另一个http请求。代码结构中存在问题,但不足以导致该错误。您确定这是引发错误的版本吗?也许可以查看使用CacheFactory进行响应。或者在http请求中指定缓存,这样您就可以再次调用它,只需接收服务d缓存结果,而不是发出另一个http请求。服务显然是在操作代码中注入到控制器中的。由于angular的引导,在加载dom内容之前不会发生顺序无关,这意味着所有组件都将在调用之前注册。我指的不是“app.controller”('AppController',函数(MyService,$scope)”,因为我可以清楚地看到他已经注入了它。我是说Angular找不到它来将其注入控制器,因为包含服务代码的文件可能在与控制器的文件之后链接。如果是这样的话,您可能会得到内部Angular
未知提供程序
错误,并且我认为您不理解引导程序ng进程和它发生的时间服务在OP代码中明显地被注入到控制器中。由于angular的引导,订单不相关,直到加载dom内容才发生,这意味着所有组件都将在调用之前注册。我不是指“app.controller('AppController',function(MyService,$scope)”,因为我可以清楚地看到他已经注入了它。我是说Angular找不到它来将其注入控制器,因为包含服务代码的文件可能在与控制器的文件之后链接。如果是这样的话,您可能会得到内部Angular
未知提供程序
错误,并且我认为您不理解引导程序ng进程,当它发生时,您仍然必须实现注释行//Else loadConfig.then return configuration您仍然必须实现注释行//Else loadConfig.then return configurations