指令不会在父作用域的$http response之后更新作用域

AngularJS : directive does not update scope after $http response in parent scope

本文关键字:作用域 http response 之后 更新 指令      更新时间:2023-09-26

我得到了这个指令:

.directive('studentTable', [function() {
    return {
        restrict: 'A',
        replace: true,
        scope: {
            students: "=",
            collapsedTableRows: "="
        },
        templateUrl: 'partials/studentTable.html',
        link: function(scope, elem, attrs) {
            ...
        }
    }
}

模板:

  <table class="table">
        <thead>
            <tr>
                <th><b>Name</b></th>
                <th><b>Surname</b></th>
                <th><b>Group</b></th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="student in students track by $index">
                <td>{{ student.name }}</td> 
                <td>{{ student.surname }}</td>
                <td>{{ student.group }}</td>
            </tr>
        </tbody>
    </table>

在我的html中像这样使用指令:

<div student-table students="students" 
    collapsedTableRows="collapsedTableRows"></div>

和父控制器:

.controller('SchoolController', ['$scope', 'User', function($scope, User){
    $scope.students = [];
    $scope.collapsedTableRows = [];
    $scope.search = function(value) {
        if(value) {
            var orgId = $state.params.id;
            var search = User.searchByOrg(orgId, value);
            search.success(function (data) {
                $scope.students = data;
                $scope.collapsedTableRows = [];
                _(data).forEach(function () {
                    $scope.collapsedTableRows.push(true);
                });
            });
        }
    }
}])

开始时,表是空的,因为student数组中没有用户。在我单击搜索并获得学生对象列表后,我将它们放入范围变量,但该指令不更新,也没有发现模型(scope.$watch('students',...)的变化。我错过了什么?

注:如果我使用$httpBackend模拟数据,则指令正常工作。

请确保数据对象返回学生数组因为有时你必须使用数据。数据,简单的演示应该帮助你:

http://plnkr.co/edit/UMHfzD4oSCv27PnD6Y6v?p =

预览
 $http.get('studen.json').then(function(students) {
      $scope.students = students.data; //<-students.data here
    },
    function(msg) {
      console.log(msg)
    })

您应该尝试这样更改控制器…

$scope.$apply(function() {
    $scope.students = data;
})
...

这将启动一个消化循环,如果它还没有进行。另一种几乎相同的形式是:

...
$scope.students = data;
$scope.$digest()
...

PS:第一个方法只是一个包装器,在计算函数后执行$rootScope.$digest(),考虑到$digest计算当前范围及其在$rootScope上调用它的所有子函数非常繁重。因此,如果第二种方法有效,应该优先使用。