Angularjs 手表未触发

Angularjs watch is not triggering

我有这个计划的三个要素。首先,在服务中,我有:

$scope.loaded = MySvc.loaded;
$scope.loaded = false;

然后,在导入这个服务的controller中,我有一系列的介绍性的东西。一旦控制器完成其异步工作,我需要在指令中触发事件,所以在控制器中,当触发器准备就绪时,我会做

MySvc.loaded = true;

然后在也导入服务的指令中,

$scope.loaded = MySvc.loaded;
$scope.$watch('loaded', function (newValue, oldValue) {

指令在 loaded 初始化为 'false' 时触发,但是当我将值更改为 'true' 时,没有任何反应。手表根本不会触发。为什么不?我该如何解决这个问题?

正如我在评论中所说,您的范围可能会覆盖 loaded 属性。

尝试使用 angular 事件来解决您的问题。

angular.module('test', [])
.controller 'MyController', ($scope, $timeout) ->
  $timeout ->
    $scope.$broadcast('READY')
  , 2000
.directive 'myDirective', ->
  scope: {}
  template: '<span>{{ value }}</span>'
  link: ($scope) ->
    $scope.value = "I'm waiting to be ready..."
    $scope.$on 'READY', ->
      $scope.value = "I'm ready!!"

See this in action(CoffeeScript,因为它的原型制作速度更快,但应该足够清晰)。

你把事情搞复杂了。改用承诺!!!他们很甜蜜。承诺保持他们的决议状态。

.factory('hello_world', function ($q, $timeout) {
   var promise = $q.defer;
   $timeout(function () {
      promise.resolve('hello world');
   }, 1000)

   return promise.promise;
 })

.controller('ctrl', function ($scope, hello_world) {
   hello_world.then(function (response) {
     console.log("I will only be ran when the async event resolves!");
     console.log(response);
   });
 });

如你所见,promises 好多了,没有 watches。没有奇怪的门。更简单,更性感。 ;)

这是一种很好的做事方式,我认为它与 promises 正交(这确实非常有用)。您的问题来自于打破您与任务创建的联系。而是尝试:

$scope.data = MySvc.data;

并附加到那个,例如MySvc.data.loaded = false。这样 data 变量永远不会重新分配,因此控制器和服务之间的链接保持不变。

然后您可以将 data.loadeddata 作为一个集合观看,方法是将 true 作为第三个选项传递给 $watch