2017-01-15 6 views
0

私は、コントローラに格納されていた多くの繰り返し機能を集中化するために、角度サービスを使用することが推奨されています。AngularJS - コントローラの再利用のためにサービスのajax結果をキャッシュする方法

私はajaxデータを(一度だけ)取り出し、キャッシュされたデータを必要に応じて再利用するためにコントローラにサービスを格納するのに良い構造を見つけることができないようです。現時点では、私はエラー:TypeError: Cannot read property 'sayHello' of undefinedを続けています。

これは、コントローラがロードされる前に私のサービスを介して自分のajaxデータをフェッチするための遅延だからです。私はこれをどのように最適化することができるのかはっきりしていない誰かがこれに良い仕組みを持っていますか?

サービス: app.service( 'MyServiceで'、関数($ HTTP){

this.sayHello = function() { 

     var deferred = $q.defer(); 

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

      var configurations = data; 
      var configurations.data_result_1 = configurations.data_result_1.split("\r\n"); 
      var configurations.data_result_2 = configurations.data_result_2.split("\r\n"); 
      deferred.resolve(configurations); 
     } 

     return deferred.promise; 
    }; 

    this.sayHello(); //Run the function upon page laod. 

}); 

コントローラ:あなたが使用していないよう

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

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

}); 
+0

コード構造に問題がありますが、そのエラーを引き起こすほどの問題はありません。これがエラーをスローするバージョンだと確信していますか? – charlietfl

+0

おそらく、あなたのレスポンスにCacheFactoryを使用してみてください。または、httpリクエストでキャッシュを指定すると、もう一度呼び出すことができます。別のhttpリクエストを行うのではなく、キャッシュ結果を提供するだけです。 https://docs.angularjs.org/api/ng/service/$http – haxxxton

答えて

1

ファクタ内のストア設定に関するBri4nと完全一致y。監視したくないと言ったのでコントローラーについては同意しませんが、一度だけデータをロードします。

しかし、$ 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(); 

私のコードは完全ではないので、私は正しく書くことができません。

+0

コメント行を実装する必要があります//その他loadConfig.then returns configuration – Sphinx117

0

OK、考え直し上で、それが見えます依存関係配列表記法を正しく変更してください。

app.service('MyService', ['$http', function ($http) { 
    // do your stuff here 
}]); 

コントローラ用:

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

// do your stuff here 

}]); 
+0

オペレーションコードでコントローラにサービスが明確に注入されています。すべてのコンポーネントが呼び出される前にすべてのコンポーネントが登録されることを意味するDOMコンテンツがロードされるまで、角度のブートストラップが発生しないため、関連はありません – charlietfl

+0

「appController」、function(MyService、$スコープ) "、私は彼がそれを注入していることをはっきりと見ることができるので、私はAngularがコントローラーにファイルを挿入して見つけることができないと言っていた。 –

+0

サービスコードを含むファイルは、その場合には不明なプロバイダのエラーです。ブートストラップのプロセスと発生するタイミングを理解していないと思っています – charlietfl

2

私がサービスを宣言するために別の方法を使用することをお勧めいたします:構成はあなたが取る変更をオブジェクトときに、その後、$ウォッチを使用することができ、あなたのコントローラで

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

}

情報:

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

    $scope.$watchCollection(function() { return MyService.getConfigurations()},function(newValue){ 
    vm.configurations = newValue; 
}); 
関連する問題