【问题标题】:directive isolate scope not triggering $watch指令隔离范围未触发 $watch
【发布时间】:2014-11-13 20:06:21
【问题描述】:

我有一个指令与它的控制器共享数据,我正在使用隔离范围。

但是,当我从指令内部更新数据时,指令和控制器都不会使用 $watch 看到数据更改。

这是我正在尝试做的一个示例:

var app = angular.module('myApp', []);

app.controller('myAppCtrl', function($scope) {
  $scope.buttonSettings = {
    val: 0
  }

  $scope.$watch('buttonSettings.val', function(val) {
    console.log('watchInController')
    console.log(val)
  });
});

app.directive('buttonTest', function() {
  return {
    restrict: 'E',
    scope: {
      buttonSettings: '='
    },
    template: '<button>{{buttonSettings.val}}</button>',
    link: function(scope) {
      var button = $('button');

      console.log(scope.buttonSettings)

      scope.$watch('buttonSettings.val', function(val) {
        console.log('watchInDirective')
        console.log(val)
      });

      button.bind('mouseover', function() {
        scope.buttonSettings.val++;
        console.log('mouseover')
        console.log(scope.buttonSettings.val)
      })
    }
  }
});

这是 plunkr 中的完整示例:http://plnkr.co/edit/lnztoMhtU03Qzl0BaMpk?p=preview

我做错了什么?

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    首先,你不应该那样使用 jQuery。您可以使用 element 参数将其注入到指令中,而不是使用 jQuery 选择按钮。

    其次,你需要在你的指令和控制器中使用$scope.$apply来触发watch。

    app.directive('buttonTest', function() {
      return {
        scope: {
          buttonSettings: '='
        },
        link: function(scope, element) {
          element.bind('mouseover', function() {
            scope.$apply(function() {
              scope.buttonSettings.val++;
            });
          })
        }
      }
    });
    

    看看这个工作plunker。

    【讨论】:

      【解决方案2】:

      halilb 是正确的,您不应该使用 jQuery 来选择元素,而是使用 Angular 为您的指令提供的元素,并且需要 $scope.$apply 来注册发生在 Angular 上下文之外的事件。但是,您根本不需要制定新指令来解决您的问题。只需使用 Angular 的 ngMouseover 指令。您可以将一个函数绑定到它,或者直接在其中添加您的逻辑。这是一个非常简单的示例。

      <div ng-init="foo = 1">Value: {{foo}}</div>
      <button ng-mouseover="foo = foo+1">Mouse over this: {{foo}}</button>
      

      以下是相同代码在将逻辑移至控制器后的样子:

      <div>Value: {{foo}}</div>
      <button ng-mouseover="incrementFoo()">Mouse over this: {{foo}}</button>
      

      控制器:

      $scope.foo = 1;
      $scope.incrementFoo = function() {
        ++$scope.foo;
      };
      

      Live demo

      【讨论】:

      • 我确实知道 ngMouseover - 我没有在示例中使用它,因为我需要一种简单的方法来演示我遇到的问题。
      猜你喜欢
      • 2014-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多