Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS-我如何知道父控制器上的承诺何时得到解决?_Javascript_Angularjs - Fatal编程技术网

Javascript AngularJS-我如何知道父控制器上的承诺何时得到解决?

Javascript AngularJS-我如何知道父控制器上的承诺何时得到解决?,javascript,angularjs,Javascript,Angularjs,我有一个指令,它依赖于来自其父控制器的数据。此数据以承诺的形式返回。我如何知道父控制器上存在的承诺何时得到解决 父控制器 angular.module("UserShoes").controller("UserController", function ($scope) { $scope.user = User.get({ userId: 1 }); $scope.shoes = []; $scope.user.$promise.then(function (dat

我有一个指令,它依赖于来自其父控制器的数据。此数据以承诺的形式返回。我如何知道父控制器上存在的承诺何时得到解决

父控制器

angular.module("UserShoes").controller("UserController", function ($scope) {
  $scope.user = User.get({
    userId: 1 
  });

  $scope.shoes = [];

  $scope.user.$promise.then(function (data) {
    data.shoes.forEach(function (shoe, index) {
      if (shoe) {
        $scope.shoes.push(shoe);
      }
    });
  });
});
指示

angular.module("UserShoes").directive("Shoes", ["", function () {
  return {
    ...

    controller: function ($scope) {
      // When will $scope.parent.shoes be ready? :-(
    }
    ...
  }
}]);

您可以广播一个事件,并在指令中侦听该事件

从父控制器:

angular.module("UserShoes").controller("UserController", function ($scope) {
      $scope.user = User.get({
        userId: 1 
      });

      $scope.shoes = [];

      $scope.user.$promise.then(function (data) {
        data.shoes.forEach(function (shoe, index) {
          if (shoe) {
            $scope.shoes.push(shoe);
          }
        });
        $scope.$broadcast('shoes-ready',$scope.shoes);
      });
    });
根据你的指示

$scope.$on('shoes-ready',function(evt,shoes){ /*process shoes*/})

$promise
导入指令的范围应该可以很好地工作。使用
&
将其作为绑定表达式导入:

视图:

然后,在指令的
链接
函数中,您可以使用已解析的承诺执行以下操作:

function link(scope) {
  scope.shoesPromise()
    .then(function(){
      ...
    })
    .catch(...)
}

我不会使用$broadcast(理论上讲,这会很贵),而是在控制器中使用$watch和一个flag。比如:

angular.module("UserShoes").controller("UserController", function ($scope) {
  $scope.user = User.get({
    userId: 1 
  });

  $scope.shoes = [];

  $scope.user.$promise.then(function (data) {
    data.shoes.forEach(function (shoe, index) {
      if (shoe) {
        $scope.shoes.push(shoe);
      }
    });
    $scope.shoes_ready = true;
  });
});
然后在你的指令中:

var stop_watch = scope.$watch('shoes_ready', function(new_value) {
  if (new_value === true) {
    // do work son
    stop_watch();  // Optional, if you are done with this watcher
  }
});

提示:控制器的匿名函数对调试和代码清洁没有帮助。有关更多详细信息,请参见John Papa。事件处理程序
shoes ready
的第一个参数将是
event
对象,而不是shoes数组。这将起作用,但理想情况下,事件应保留给系统上真正的全局事件,而这是一个非常局部的问题。嗯,如果他最终在UserController下面有很多嵌套的作用域,那么这可能会非常昂贵。我不确定这是否是最有效的解决方案。公平地说,Angular中的事件处理在最近的版本中效率更高,而且它只会在注册了事件处理程序的情况下真正遍历作用域。所以它不再像以前那样低效了。只需将值加载到我的页面的主控制器上,并允许指令引用那里的值,可以吗?我认为,这解决了问题的整个时间方面。就我个人而言,调用scope属性
shoes
shoesPromise
对我来说更有意义
ngModel
意味着双向绑定,而这只是单向绑定。(这意味着您最好使用
&
而不是
=
,因为您不需要双向绑定)。但是,如果您使用
&
,则需要将其作为作用域上的方法调用:
scope.shoesPromise()。然后(…
只需将值加载到我的页面主控制器上并允许指令引用那里的值就可以了吗?我认为这就解决了问题的整个计时方面。我不会说取消手表注册是可选的,你应该始终在使用完手表后删除它们。你也不需要这样做要用watch deregistration函数来扰乱作用域,它只需要是一个局部变量。啊,局部变量是对的。但我想说它是可选的,因为他可能不需要它。假设他正在制作某种滚动条,这个指令控制无限滚动条。保持它的注册是有意义的,因为他会这样做最终加载更多的鞋子。但我不知道他的应用程序做什么,也不知道这个指令是如何使用的。这听起来像是一个例子。
shoes\u ready
变量是一个布尔值,承诺不能被多次解析,所以它只能从
false
变为
true
一次。你甚至可以使用新的
::shoes\u ready
bind once语法,以避免可能需要自己取消注册观察者。只需将值加载到我的页面的主控制器上并允许指令引用那里的值就可以了吗?我想这会解决问题的整个计时方面。您所说的值是指
$scope.shoes
?如果可以,那么是的,这将uld是实现这一点的首选方法。只要它不是孤立的,它已经在指令的范围内可用。
angular.module("UserShoes").controller("UserController", function ($scope) {
  $scope.user = User.get({
    userId: 1 
  });

  $scope.shoes = [];

  $scope.user.$promise.then(function (data) {
    data.shoes.forEach(function (shoe, index) {
      if (shoe) {
        $scope.shoes.push(shoe);
      }
    });
    $scope.shoes_ready = true;
  });
});
var stop_watch = scope.$watch('shoes_ready', function(new_value) {
  if (new_value === true) {
    // do work son
    stop_watch();  // Optional, if you are done with this watcher
  }
});