【问题标题】:Angular: update in factory model does not reflect in controllerAngular:工厂模型中的更新不会反映在控制器中
【发布时间】:2013-06-25 10:16:51
【问题描述】:

我有一个保存用户偏好值的用户偏好工厂。当页面加载时它是空的。用户登录后,将填写用户个人资料。 伪代码

app.factory('pref', function($rootScope){
    var pref = {}, age, name;        
    $rootScope.$on('logged.in', function(){
      pref.name = 'sam';
      pref.age = 30;
      pref.currency = '$';

      age = getAge(); name = getName();
    })

    function getName(){
      //format name
      return name;
    }
    function getAge(){
      return age;
    }  
    return {
      currency: pref.currency,
      age: age,
      name: name
    }
  })

然后我在我的控制器中注入工厂:

app.controller('MainCtrl', function($scope, pref) {
  $scope.name = pref.name; //Return undefined
  var currency = pref.currency;
  $scope.price = function(amount){
    return amount + currency; //don't show $ sign
  }
});

预设工厂的返回值未在控制器中更新。如何让它发挥作用?

编辑:plunkr http://plnkr.co/edit/SKJC5hUPEm72JqGJyT9y

【问题讨论】:

  • 我没有在你的代码中看到logged.in你能告诉你在哪个位置触发事件
  • 是我还是你从来没有为名称设置值?控制器中的 pref.name 调用 getName() 返回 name,但 name 然后再次调用 getName()? pref.name 已设置,但这是一个不同的对象,而不是您返回的对象。
  • @Ajaybeniwal 这是一个伪代码。当成功登录时,我的登录服务会发出事件,此时pref 对象中的值已设置。在此之前 pref 是一个空对象
  • 你能发布一个显示问题的 JSFiddle 或 Plunker 吗?可能存在许多问题,并且发布与您遇到的问题不同的代码并不能真正帮助任何人调试它。
  • @rtcherry 添加了一个 plunker 来说明问题

标签: javascript angularjs


【解决方案1】:

pref工厂返回的对象,

{ setPreference: setPreference,
  currency: pref.currency,
  name: pref.name,
  formatTime: formatTime }

currencyname 分配给未定义的属性。由于undefined 不是引用类型,currencyname 不会“看到”对象pref 的任何更新。

我建议将引用 pref 对象的属性作为工厂返回的对象的一部分:

{ setPreference: setPreference,
  prefs: pref,
  formatTime: formatTime }

现在,我们对pref 所做的任何更新都将反映在prefs 中。在您的控制器中参考该对象的属性,如下所示:

console.log(prefService.prefs.name)

为了不改变pref指向的引用,使用angular.copy()修改pref引用的对象:

function setPreference(values){
   //pref = values;   <<-- won't work, since pref will now reference another object
   angular.copy(values,pref);
}

更新:要让视图在name 更改时自动更新,我建议将prefs 的引用保存为范围属性:

$scope.prefs = prefService.prefs;

然后在视图/HTML中使用{{prefs.name}}

<p>Hello {{prefs.name}}!</p>

更新plunker

【讨论】:

  • 谢谢!我明白这个问题。现在我的服务方法已经更新了值,但是我的范围属性仍然没有更新。 $scope.name = prefService.prefs ? prefService.prefs.name : null; name 永远不会在视图中更新
  • 感谢完美的人!但是有一个问题,为什么需要将它放在范围内?我假设它与摘要周期有关,但在 dygest $scope.name 应该再次评估 prefService.prefs.name
  • @SamSerious, $scope.name = prefService.prefs.nameprefService.prefs.name 的原始值分配(复制)到$scope.name$scope.name 不会在摘要周期中更新。您必须设置一个$watch() 才能做到这一点。对于$scope.prefs = prefService.prefs,我们正在处理一个引用。如果被引用的对象发生了变化,那么引用它的对象将会看到变化——这是一种语言/JavaScript 特性。此处也不涉及摘要循环。
猜你喜欢
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
  • 2011-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-23
  • 1970-01-01
相关资源
最近更新 更多