Javascript 如何延迟ng init方法直到范围变量加载完毕?

Javascript 如何延迟ng init方法直到范围变量加载完毕?,javascript,angularjs,Javascript,Angularjs,在我的项目中,我有一个包含多个单元格的表。在每个单元格中,我都有一个带有初始值的下拉菜单。当页面加载时,我调用ng init中的一个函数,该函数返回此下拉菜单的正确值 我的问题是,这个函数依赖于通过对服务器的异步调用获得的值。这意味着,有时如果表很大,则在ng init之后加载必要的数据。这样我就无法正确初始化下拉列表 所以基本上我只需要一种方法来确保当调用nginit时,所有数据都已经从服务器接收到了 通常我会在从服务器获取所有数据后使用$scope变量来简单地更新视图,但我不能在这里这样做,

在我的项目中,我有一个包含多个单元格的表。在每个单元格中,我都有一个带有初始值的下拉菜单。当页面加载时,我调用ng init中的一个函数,该函数返回此下拉菜单的正确值

我的问题是,这个函数依赖于通过对服务器的异步调用获得的值。这意味着,有时如果表很大,则在ng init之后加载必要的数据。这样我就无法正确初始化下拉列表

所以基本上我只需要一种方法来确保当调用nginit时,所有数据都已经从服务器接收到了

通常我会在从服务器获取所有数据后使用$scope变量来简单地更新视图,但我不能在这里这样做,因为我需要为表中的每个单元格使用$scope变量,并且表具有动态宽度和高度

有什么办法解决这个问题吗

下面是我的意思的一个简短代码示例:

HTML:

从服务器加载数据的Javascript:

dataService.getPersons(curView, function(result) {
  var persons = JSON.parse(result);

  if (persons.length) {

    for (var i = 0;i < persons.length; i++) {
      $scope.persons.push(persons[i]);
        $scope.$apply();
      }
    }
    });
初始化下拉列表的Javascript:

self.getConnectionType = function(id1, id2) {

        for (var i = 0; i < $scope.persons.length; i++) {
            if ($scope.persons[i].sourceId === id1&& $scope.persons[i].id2=== activityId) {
                return $scope.persons[i].connectionType;
            }
        }
    };

您可以在表上使用带有ng if=的$scope变量,并且只有在获得所有数据后才显示它?

您可以使用以下代码:

angular.element(document).ready(function () {
    $timeout(function () {
        //$scope.init(); Your loading method
    }, 500)

});

在这里,你可以调用你的init方法

基于上面的好评论,如果你可以帮助的话,不要使用ng init,因为你可以在CTRL中初始化所有你需要的东西。只需将$scope.persons的init和下拉连接类型的init组合起来即可

.controller("MyCtrl", function() {
  var init = { 
     connectionType: function(id1, id2) {
       angular.forEach($scope.people, function(person) {
         if (person.sourceId == id1 && person.id2 == activityId) {
           $scope.connectionType = person.connectionType;
         }
       });
     },

     people: function() {
       dataService.getPersons(curView).
         then(function(response) {
           // depending on what response brings back, my APIs return a 'data' property for each response
           $scope.people = angular.copy(response.data);

           if ($scope.people.length > 1) {
             var person1 = $scope.people[0],
                 person2 = $scope.people[1];

             // set up the connectionType between person1 and person2
             init.connectionType(person1.id, person2.id);
           }
         });
      }
  }

  // gets called when CTRL is initialized;
  init.people();
})

请添加您正在使用的javascript和html,特别是调用后发生的内容resolves@NathanBeck我刚刚添加了一些代码示例,希望这有助于将初始化代码移动到控制器内部,并在数据从服务器到达后调用它。ng init指令可能被滥用,从而在模板中添加不必要的逻辑量。这种模型和视图的制作方式使得代码更难理解、调试、测试和维护。您应该使用控制器而不是ngInit来初始化scope@georgeawg我会试试看,谢谢。出于好奇,您使用什么基于回调的API从服务器获取数据?通常,基于回调的API应该转换为返回AngularJS承诺。转换应该在服务内部完成,这样控制器就不需要执行$scope.$apply。我已经尝试过了,但问题是即使表被隐藏,也会调用ng init。因此,它将在加载所有数据后显示表,但值错误,因为它不调用ng init againGet rid of ng init。这不是最佳做法,在获得数据之前隐藏表,然后使用ng if显示它。您不需要ng-init。这只是在加载文档后调用init函数,而此时已经发生了这种情况。在这个angular.element中,在调用init函数之前编写$timeout函数。$timeout的使用是一种代码气味,是一个更基本问题的症状。避免$timeout并寻求更健壮的解决方案。
.controller("MyCtrl", function() {
  var init = { 
     connectionType: function(id1, id2) {
       angular.forEach($scope.people, function(person) {
         if (person.sourceId == id1 && person.id2 == activityId) {
           $scope.connectionType = person.connectionType;
         }
       });
     },

     people: function() {
       dataService.getPersons(curView).
         then(function(response) {
           // depending on what response brings back, my APIs return a 'data' property for each response
           $scope.people = angular.copy(response.data);

           if ($scope.people.length > 1) {
             var person1 = $scope.people[0],
                 person2 = $scope.people[1];

             // set up the connectionType between person1 and person2
             init.connectionType(person1.id, person2.id);
           }
         });
      }
  }

  // gets called when CTRL is initialized;
  init.people();
})