一起使用隔离范围和嵌入式指令控制器

时间:2014-04-07 19:15:35

标签: javascript angularjs angularjs-directive angularjs-scope

我一直在使用指令,但我正冒险使用隔离范围构建它们。

我很难理解隔离范围如何与指令控制器结合使用。一旦我隔离了作用域,模板就无法再访问指令控制器上的作用域函数。

以下是一个例子:

http://plnkr.co/edit/NWa7nZzjoncKEXwuvSKo?p=preview

我已经阅读过有关使用范围绑定的内容,但似乎它应该与“父”范围进行交互,并且我认为嵌入式控制器将成为隔离范围的一部分。

3 个答案:

答案 0 :(得分:2)

对于新手来说,这是一个难题。我打算在这里写一份简历让你明白。

当你做的事情如下:

<my-directive>
  <button ng-click="doSomething()">Do Something</button>
</my-directive>

您首先想到的是<my-directive>内的所有内容,在这种情况下<button>是指令的一部分。事实并非如此。

内部是什么,<button>被称为transcluded html。那个transcluded html有一个新的范围,它无法访问指令的孤立范围,实际上它们是兄弟姐妹。

具体来说,有一个控制器的范围,从那里有一个隔离的范围和一个新的范围,用于转换的html。

因此,由于被转换的html无法访问隔离范围,因此ng-click根本不会触发。

有解决方法。

所以在这种情况下,我再说一遍,doSomething存在于隔离范围内,该按钮正在查看transcluded html及其父级(控制器范围)的新范围,并且它没有'存在。

sh3nan1gans给你的解决方案正在发挥作用,但我个人不会这样做。

它是如何工作的?由于它创建了与控制器范围的双向绑定,因此它在隔离时创建新函数,然后它也在父节点上创建。然后按钮将在该父作用域中找到该函数,然后运行它。

如果您需要更多信息,包括解决方法,请查看here

答案 1 :(得分:1)

在html中添加函数到你的指令:

<my-directive do-something="doSomething">
  <button ng-click="doSomething()">Do Something</button>
</my-directive>

在你的指令文件中:

scope: {
    doSomething: '='
  }

更新了plunker: http://plnkr.co/edit/0qxipiBvVFEC1huBPGNM?p=preview

答案 2 :(得分:1)

因为您的新指令和隔离范围编译之前您的按钮就在那里,所以它们被分配到父范围而不是您正在制作的新范围。如果您希望将按钮附加到新范围,则需要使用injectable transclude和linker函数来移动html并将其编译到新范围,如下所示:

angular.module('directives',[]) .directive('myDirective', function(transclude) { return { restrict: 'E', transclude: true, scope: {}, controller: function($scope, $element, $attrs, ctrl, transclude) { transclude(function(clone){ $element.append(clone); $scope.doSomething = function() { alert('I did something'); } }); } } });