在指令的链接函数中修改事件中的范围变量

时间:2015-01-29 05:52:43

标签: javascript angularjs angularjs-directive angularjs-scope

我在指令的链接函数中的元素上有一个jQuery事件。我想在该事件回调中修改范围变量。它不起作用 - 使该变量永远不会更新的模板:

joyableApp.directive('foobar', [function() {
  var FoobarLink = function(scope, element, attrs){
    scope.foo = 'bar';
    element.click(function(){
      console.log("clicked!");
      scope.foo = 'clicked_result';
    });
  };
  return {
    template: '<div>foo = {{foo}}</div>',
    scope: {},
    link: FoobarLink
  }
}]);

在这个例子中,我试图在单击指令元素时更新scope.foo。但是,当我运行此单击并单击该元素时,模板不会从bar更新为clicked_result。我怀疑我遗漏了关于linkscope如何在这里工作的基本信息。

一些不相关的背景故事,以防它有所帮助:我正在尝试创建一个指向<input>字段的指令。当您专注于此输入字段时,它将显示弹出工具提示。因此,使用该指令的接口看起来像<input input-tooltip content=‘some tooltip content here’>。但是,要做到这一点,我需要指令来监听focus事件的根元素。我能找到的唯一方法是在传递给link函数的元素上使用jQuery事件。但是,在该事件的焦点事件的回调中,我似乎无法成功修改范围变量。

3 个答案:

答案 0 :(得分:1)

将$操作包装在$ timeout中。

  element.click(function(){
    console.log("clicked!");
    $timeout(function () {
      scope.foo = 'clicked_result';
    },0);

  });

$ timeout将导致安全的摘要周期开始。 别忘了注入$ timeout:

joyableApp.directive('foobar', ['$timeout', function($timeout) {

希望这有帮助。

答案 1 :(得分:1)

  element.click(function(){
    console.log("clicked!");
    scope.$apply(function () {
      scope.foo = 'clicked_result';
    });

  });

使用$ apply是合适的,不需要注入$ timeout。根据我的经验,$ timeout仅在您修改链接函数中的DOM并且需要等待angular来编译添加的元素的情况下才有用。

答案 2 :(得分:1)

在Angular遇到digest loop之前,

$scope.foo将不会刷新,这就是所谓的dirty check。在指令中,您需要自己手动触发摘要循环,如下所示

scope.$apply(function () {
  scope.foo = 'clicked_result';
});

但您可能会遇到Error: $digest already in progress,因此您最好使用evalAsyncapplyAsync来触发安全的摘要周期,例如

scope.$evalAsync(function () {
  scope.foo = 'clicked_result';
});