【问题标题】:Auto-updating scope variables in angularjs在angularjs中自动更新范围变量
【发布时间】:2014-02-04 20:26:18
【问题描述】:

我目前正在使用 AngularJS。我想从服务中返回一个变量,该变量将让作用域知道它何时发生了变化。

为了说明这一点,请查看 www.angularjs.org 中的示例“连接后端”。大致上,我们可以看到以下内容:

var projects = $firebase(new Firebase("http://projects.firebase.io"));
$scope.projects = projects;

此后,对projects 对象所做的所有更新(通过更新,无论是本地还是远程)都将自动反映在范围绑定到的视图上。

我怎样才能在我的项目中实现同样的目标?就我而言,我想从服务中返回一个“自我更新”变量。

var inbox = inboxService.inboxForUser("fred");
$scope.inbox = inbox;

什么机制让$scope知道它应该更新?

编辑: 针对这些建议,我尝试了一个基本示例。我的控制器:

$scope.auto = {
    value: 0
};

setInterval(function () {
    $scope.auto.value += 1;
    console.log($scope.auto.value);
}, 1000);

而且,在我看来:

<span>{{auto.value}}</span>

不过,它只显示 0。我做错了什么?

【问题讨论】:

    标签: angularjs scope


    【解决方案1】:

    更新:

    我做了一个演示 plunker:http://plnkr.co/edit/dmu5ucEztpfFwsletrYW?p=preview
    我使用$timeout 伪造更新。


    诀窍是使用纯 javascript 引用:

    • 您需要将对象传递给范围。
    • 您不能覆盖该对象,只需更新或扩展它。
    • 如果您覆盖它,您将失去“绑定”。
    • 如果您使用$http,它将为您触发摘要。
    • 因此,每当发生更改时,范围变量都会引用服务中更新的同一对象,并且所有观察者都会收到摘要通知。
    • AFAIK,这就是 $firebaseRestangular 的工作原理。
    • 如果您进行多次更新,您需要有一种重置属性的方法。
    • 由于您在整个应用程序中持有对对象的引用,因此您需要注意内存泄漏。

    例如:

    服务:

    app.factory('inboxService', function($http){
    
      return {
        inboxForUser: function(user){
    
          var inbox = {};
    
          $http.get('/api/user/' + user).then(function(response){
            angular.extend(inbox, response.data);
          })
    
          return inbox; 
        }
      };
    });
    

    控制器:

    app.controller('ctrl', function(inboxService){
      $scope.inbox = inboxService.inboxForUser("fred");
    });
    

    【讨论】:

    • 谢谢。如我编辑的问题所示,我尝试应用您的解决方案(更新对象),但无法使其正常工作。有什么想法吗?
    • @Antoine_935 你能分享一个plunker让我看看吗?
    • 嗯。做这个 plunker 让我意识到我应该在这个例子中使用 $timeout 代替。好吧,它应该可以工作 :) plnkr.co/edit/OWjMT9hWCn4ujjCnc7eQ?p=preview 谢谢你告诉我 plunker btw,不知道!
    • 但是,我应该自己打电话给$digest吗? (可能没有人会在我的情况下)。如果我手头没有示波器,我该怎么称呼它?不确定我想在$rootScope 上打电话,它可能很重。
    • 即使你在任何范围内触发 $apply ,它总是会在 $rootScope 上触发摘要。这是一个已知问题,Angular 团队目前正在研究解决方案。
    【解决方案2】:

    这取决于对象的更新方式。如果它在“内部”角度更新,将触发一个摘要循环(参见http://docs.angularjs.org/guide/scope),并且视图将自动更新。这就是 Angular 的美妙之处。

    如果对象在 Angular 的“外部”更新(例如 jQuery 插件),那么您可以通过将执行更新的代码包装在 $apply 函数中来手动触发摘要循环。像这样的:

    $scope.$apply(function() {
        //my non angular code
    });
    

    请参阅http://docs.angularjs.org/api/ng.$rootScope.Scope 了解更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多