2

コントローラー間でデータを共有するためにサービスを使用しています。ただし、サービスは、新しいリクエストを行った場合でも、キャッシュされたデータを使用して promise を返しています。インスタンスが作成される場所に応じて、deferライブ データが返されるが双方向バインディングが壊れるか、双方向バインディングが機能するがキャッシュされたデータが返されます。

キャッシュされたデータで promise が返されるのを防ぎ、双方向バインディングを維持するにはどうすればよいでしょうか?

ケースを説明するためにプランカーを用意しました: http://plnkr.co/edit/SyBvUu?p=previewそして完全を期すために、ここにトラブルメイキングサービスがあります:

app.service('myService', function($http, $q) {

    // When instancing deferred here two way binding works but cached data is returned
    var deferred = $q.defer();

    this.get = function(userId) {
        // When instancing deferred here two way binding breaks but live data is returned
        //var deferred = $q.defer();

        console.log('Fetch data again using id ', userId);
        var url = userId + '.json';
        $http.get(url, {timeout: 30000, cache: false})
            .success(function(data, status, headers, config) {
                deferred.resolve(data, status, headers, config);
            })
            .error(function(data, status, headers, config) {
                deferred.reject(data, status, headers, config);
            });
        return deferred.promise;
    };

});

更新: 問題は、データがキャッシュされたことではなく、データを共有する方法を理解していなかったことと、共有データをプリミティブにすることができないことでした。以下の私自身の答えを参照してください。

4

2 に答える 2

0

Luke Kende の助けを借りて、データを共有するための単純化されたソリューションを思いつきました。ここにプランクがあります: http://plnkr.co/edit/JPg1XE?p=preview . 以下のコードを参照してください。

重要なことの 1 つは、共有オブジェクトがプリミティブではないということです。さまざまな解決策を試したとき、共有オブジェクトを宣言してそれを割り当てることから始めましたがnull、これはノーノーです。空のオブジェクトを使用すると機能します。

var app = angular.module('plunker', []);

// Service
app.service('myService', function($http, $q) {

    //object that will be shared between controllers
    var serviceData = {
        items: []
    };

    return {
      data: serviceData, //pass through reference to object - do not use primitives else data won't update
      get: function(url, overwrite) {
          if (serviceData.items.length === 0 || overwrite){
              $http.get(url, {timeout: 30000})
                  .success(function(data, status, headers, config) {
                    //could extend instead of ovewritting
                    serviceData.items = data;
                  })
                  .error(function(data, status, headers, config) {
                      serviceData.items = {status: status};
                  });
          }
          return serviceData;
      },
      empty: function(){
          serviceData.items = [];
      },
      more: function(){
          //do some other operations on the data
      }
    };
});

// Controller 1
app.controller('FirstCtrl', function( myService,$scope) {

    //myService.data is not initialized from server yet
    //this way don't have to always use .then() statements
    $scope.data = myService.data; 

    $scope.getTest = function(id){
        myService.get('test' + id + '.json',true);
    };
    $scope.addItem = function() {
        $scope.data.items.push({'title': 'Test ' + $scope.data.items.length});
    };
    $scope.delItem = function() {
        $scope.data.items.splice(0,1);
    };

});

// Controller 2
app.controller('SecondCtrl', function( myService,$scope) {

    //just attach myService.data and go
    //calling myService.get() results in same thing
    $scope.data = myService.data;

    //update the the data from second url -
    $scope.getTest = function(id){
        myService.get('test' + id + '.json',true);
    };

    $scope.empty = function(){
       myService.empty();
    };
});
于 2013-08-22T08:59:54.110 に答える