在源更改后重新生成Angular工厂提供的数据

时间:2016-03-21 09:21:07

标签: angularjs ionic-framework angular-ui-router

我将我的应用程序简化为此示例,因此我知道这个特殊情况可以更轻松地完成,但我想保留应用程序的原始结构。

所以,这里我在开头设置了一个rootScope(这个模拟了原始应用程序的数据源):

.run(function($rootScope){
  $rootScope.initarray = [1,1];
})

有两家工厂:

priceFactory以异步方式返回$ rootScope.initarray。

doublePrice工厂从priceFactory获取数组,并将每个项目加倍。

.factory('priceFactory', function ($rootScope, $q, $timeout) {
    var deferred = $q.defer();
    $timeout(function() {
        deferred.resolve($rootScope.initarray)
      }, 1000);
    console.log('priceFactory');
    return deferred.promise;
})

.factory("doublePrice", function (priceFactory) {
  console.log('doublePrice');
  return priceFactory.then(
    function(data){
      var temp = [];
      for (i in data){
        temp.push(data[i]*2)
      }
      return temp;
    });
})

我还有两个ui-route状态,一个显示doublePrice返回的数据,第二个状态有一个按钮,可以向$rootScope.initarray添加一个新元素。

我的问题是,当我在第二个状态向$ rootScope.initarray添加一个新元素时,我必须更新第一个状态中显示的数据。

Here's a codepen example about the issue.

所以,问题是:是否有任何简单的方法来实现更新。我正在使用angular with ionic,它不是缓存问题,但工厂和ui-router状态解析在应用程序运行期间返回相同的数据。

1 个答案:

答案 0 :(得分:1)

使用factory服务表明返回值在第一次注入时缓存,并在后续注入时重复使用。这是所需的行为,无法更改。

每次路线变更都需要获得新的承诺是路线解析器的常见情况。另一种方法是使用返回函数的factory服务:

.factory('priceFactory', function ($rootScope, $timeout) {
  return function () {
    // no deferred antipattern is necessary here
    return $timeout(function() {
        return $rootScope.initarray;
    }, 1000);
  };
});

所以它可以这样使用(如果应该向函数提供$state的其他参数,那就很好):

priceResolver: function (priceFactory) {
  return priceFactory();
}

或者它可以是service服务,这是解析器的完美用例,因为它会在每次注入时发出一个新实例。 service服务将其实例设为this,但他们可以忽略它并返回一个新对象:

.service('priceService', function ($rootScope, $timeout) {
  return $timeout(function() {
      return $rootScope.initarray;
  }, 1000);
});