简体   繁体   English

角度视图未更新

[英]Angular view not updated

If I modify $scope after a $timeout, my view doesn't get rendered properly. 如果在$ timeout之后修改$ scope,则无法正确呈现我的视图。 I don't understand why. 我不明白为什么。 It works if I don't do the $timeout first. 如果我不先执行$ timeout,它会起作用。

http://plnkr.co/edit/oGuPgt7VaYKgPFh00lDV?p=preview http://plnkr.co/edit/oGuPgt7VaYKgPFh00lDV?p=preview

<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js'></script>
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">

<script>

angular.module('treeApp', [])

.controller('TreeController', ['$scope', '$timeout', function($scope, $timeout) {

  // This works
  // $scope.nodes = {
  //   1:{node_id:1, text:'foo text', parent_id:null, child_ids:[2,3]},
  //   2:{node_id:2, text:'bar text', parent_id:1, child_ids:[]},
  //   3:{node_id:3, text:'abc text', parent_id:1, child_ids:[]}
  // }
  // $scope.top_ids = [1]

  // This doesn't work
  $timeout(function() {
    $scope.nodes = {
      1:{node_id:1, text:'foo text', parent_id:null, child_ids:[2,3]},
      2:{node_id:2, text:'bar text', parent_id:1, child_ids:[]},
      3:{node_id:3, text:'red text', parent_id:1, child_ids:[]}
    }
    $scope.top_ids = [1]
  }, 1000)
}])

</script>


<div ng-app="treeApp">

  <script type="text/ng-template" id="node.html">
    <li node_id="{{node_id}}" ng-repeat="node_id in node_ids" ui-tree-node
        ng-init="node = nodes[node_id]">
      {{node.text}}
      <ol ng-include="'node.html'" ng-init="node_ids = node.child_ids"></ol>
    </li>
  </script>

  <div ng-controller="TreeController">
    <ol ng-include="'node.html'" ng-init="node_ids = top_ids"></ol>
    <pre>{{top_ids | json}}</pre>
    <pre>{{nodes | json}}</pre>
  </div>
</div>
<ol ng-include="'node.html'" ng-init="node_ids = top_ids"></ol>

You initialize node_ids with top_ids . node_ids使用top_ids初始化top_ids It's a one-time assignment, not a binding. 这是一次性的任务,而不是绑定。 When you use $timeout the value of top_ids is undefined at the point of the assignment. 使用$timeout时,在分配时, top_ids的值是undefined的。

The easiest solution is to rename $scope.top_ids to $scope.node_ids and get rid of ng-init . 最简单的解决方案是将$scope.top_ids重命名$scope.top_ids $scope.node_ids并摆脱ng-init

use $scope.$apply(); 使用$scope.$apply(); like below 像下面

  $timeout(function() {
    $scope.nodes = {
      1:{node_id:1, text:'foo text', parent_id:null, child_ids:[2,3]},
      2:{node_id:2, text:'bar text', parent_id:1, child_ids:[]},
      3:{node_id:3, text:'abc text', parent_id:1, child_ids:[]}
    }
    $scope.top_ids = [1];
    $scope.$apply();
  }, 1000)

or you can wrap model changes like below, 或者您可以像下面那样包装模型更改,

$timeout(function() {    
    $scope.$apply(function () {
         $scope.nodes = {
                1:{node_id:1, text:'foo text', parent_id:null, child_ids:[2,3]},
                2:{node_id:2, text:'bar text', parent_id:1, child_ids:[]},
                3:{node_id:3, text:'abc text', parent_id:1, child_ids:[]}
         }
         $scope.top_ids = [1];
    });
}, 1000)

here is a good demo , 这是一个很好的演示

Here is the working plunker 这是工作中的笨蛋

if you change any model outside of the Angular context, then you need to inform Angular of the changes by calling $apply() manually..... For example, if you use JavaScript's setTimeout() function to update a scope model, Angular has no way of knowing what you might change. 如果您在Angular上下文之外更改任何模型,则需要通过手动调用$ apply()来通知Angular更改。例如,如果您使用JavaScript的setTimeout()函数更新范围模型Angular无法知道您可能会更改什么。 In this case it's your responsibility to call $apply() manually 在这种情况下,您有责任手动调用$ apply()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM