Angular $ scope在更新,导航和$ scope之后不绑定到视图。$ apply()

时间:2016-04-27 14:53:32

标签: javascript angularjs angular-ui-router angularjs-ng-repeat

我有一个包含列表的数据库。我有一个表单,通过factory向数据库列表添加一行。添加行后,服务器将发回更新的列表。使用$q.defer().promise返回的$http.post,我使用$scope上的更新列表更新controllerdefer.resolve的列表。

在测试的同时,我遇到了一个异象。我的问题是,如果我离开执行更新view的{​​{1}}并在更新完成之前返回controller,则更新完成时{{1}没有使用更新的列表更新 - 好吧,无论如何它都没有在view中更新。如果我离开(在SPA内),然后再返回,我会得到正确的数据。

执行更新的$scope会从view函数中的factory返回promise。当promise解决后,post会更新。

这是setData耐心等待$scope解决的代码:

controller

这是相应视图中的html,它应该与$http.post

无缝绑定
  promise.then(function() {
    $scope.people = dataService.getData();
    $scope.newperson = '';
    $scope.submitting = false;
    $scope.$apply();
  });

我在这个JSBin中模仿了一个缓慢的服务器响应(使用setTimeout):https://jsbin.com/hihazegosi/1/edit?js,console,output

重新发布问题:

  1. 导航至$scope.people
  2. 添加一个人。在控制台中查看该帖子被调用。
  3. 导航至<li class="list-group-item" ng-repeat="person in people">{{person.firstName}} {{person.lastName}}</li> 并在5秒内返回People
  4. 等待人们,并在控制台中注意该人应该被添加到范围内。
  5. 如果您导航到Home并直接返回People,您会看到该模型已更新。
  6. 注意,如果你a)在帖子完成后导航回Home,你会看到正确的数据。如果你b)留在People,你会看到正确的数据。调用People时不会检查People,因为在所有情况下都会返回$scope.$apply(),因此您会在方案b中看到错误。

    有人可以解释这里发生了什么,是否有办法让$scope.$$phase'$digest'在这种情况下保持同步?

1 个答案:

答案 0 :(得分:4)

我相信发生的事情就是这样:

  • 当您远离人员状态时,控制器及其范围将被销毁
  • 因此当dataService.setData承诺解决时,它所拥有的$scope并不是指人员控制器的范围(它指的是你导航之前的旧控制器)。
  • 当您之后切换到主页并返回给人员时,会再次重新创建人员控制器,并在其构造函数中执行dataService.getData,然后使用正确的值填充其$scope.people

我认为您需要将状态列表保存在状态更改的某个位置,例如:在dataService服务中

您还可以使用$broadcast在需要更新时将消息传递给控制器​​。你可以这样做:

  • dataService.setData结算时$rootScope.$broadcast('peopleUpdated') - 这将从根范围向下发送一条消息,直至您应用中的所有范围
  • 使用$scope.$on('peopleUpdated', function() { $scope.people = dataService.getData(); })
  • 在控制器中收听此事件