2014-11-10 5 views
1

Если я изменил $ scope после $ timeout, мое представление не получилось должным образом. Я не понимаю, почему. Он работает, если я сначала не делаю $ timeout.Угловой взгляд не обновляется

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> 
+0

Попробуйте назначить переменную $ scope переменной и использовать эту переменную в тайм-ауте или, возможно, предоставить скрипт – Fyre

+0

Я попытался назначить переменную $ scope переменной, но это не устранило проблему. Я предоставил plunkr (см. Ссылку прямо над кодом). –

+0

Никогда не используйте 'ng-init', если вам не нужно сохранять внешний индекс в вложенном' ng-repeat'. – Miraage

ответ

1
<ol ng-include="'node.html'" ng-init="node_ids = top_ids"></ol> 

Вы инициализировать node_ids с top_ids. Это одноразовое задание, а не обязательное. Когда вы используете $timeout, значение top_ids равно undefined в точке назначения.

Самое легкое решение - переименовать $scope.top_ids в $scope.node_ids и избавиться от ng-init.

0

использование $scope.$apply();, как показано ниже

$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) 

или вы можете обернуть модели изменения, как ниже,

$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) 

здесь является хорошим demo,

Здесь работает plunker

если изменить любую модель за пределами углового контекста, то вам необходимо сообщить Угловыми изменения, вызвав $ применить() вручную ..... Например, если вы используете Функция setTimeout() JavaScript для обновления модели области, Angular не имеет возможности узнать, что вы можете изменить. В данном случае это ваша ответственность, чтобы вызвать $ применить() вручную

+1

Это не решит проблему. Я уверен, что $ timeout автоматически называет $ apply. –

+0

Этот plunkr не работает. Предполагается, что это дерево, обработанное над сырым json. Раскомментируйте прокомментированный код, чтобы увидеть его. –

Смежные вопросы