【问题标题】:Access directive's isolate scope from within transcluded content访问指令的隔离范围与嵌入的内容
【发布时间】:2013-04-16 19:42:43
【问题描述】:

我不确定这是否真的可行,但我本质上是想要 AngularJS 中的 '&' 隔离范围的反向。这是一个Plunkr 来演示。

基本上,我设置了一个自定义指令来提供一些可重用的 HTML。它利用ng-transclude 允许在其中呈现一些外部内容。但是,我发现了一种情况,我想从代码的嵌入部分访问已在指令的隔离范围上设置的函数。

所以基本上我有一些看起来像:

<div ng-controller="MainController">

    <!-- The directive -->
    <div some-custom-directive>

        <!-- Button 1 that invokes a method within the controller scope -->
        <button id="button1" ng-click="invoke1()">Invoke from Controller</button>

        <!-- Button 2 that invokes a method on the isolate scope for the custom directive -->
        <button id="button2" ng-click="invoke2()">Invoke from Isolate Scope</button>
    </div>
</div>

有人知道这是否真的可能吗?

更新

根据@Mark Rajcok 的回答,$scope 上的$$prevSibling 可用于从嵌入内容中访问指令的隔离范围。但是,我已经更新了上面的 Plunkr 以从 ng-repeat 指令中尝试此操作,但该指令不起作用。我假设该重复中的项目不继承范围。

【问题讨论】:

    标签: javascript html angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    这是一个解决您当前问题的解决方案。我不确定您要做什么。但据我所知,没有办法从外部范围调用隔离范围内的东西。当然,您可以在隔离作用域和外部作用域之间设置双向绑定变量,更改外部作用域中的变量并在隔离作用域上 $watch (这将像事件机制一样工作)......这是一个做你想做的事的方式..如果你坚持的话。

    另外,有一种机制可以从隔离作用域调用外部作用域上的函数。有点像回调。

    看到这个http://plnkr.co/edit/5MT4vo9qXtV6nQikfEiH?p=preview

    【讨论】:

      【解决方案2】:

      虽然可能,但我提出的解决方案是一个 hack,因为它使用范围内部变量 $$prevSibling

      在您被嵌入的内容中,您处于被嵌入的范围内。该指令的隔离和嵌入范围是同级的。要从嵌入范围到隔离范围,可以使用$$prevSibling。 (要从隔离作用域到转入作用域,可以使用$$nextSibling。)

      所以,这个 hack 会起作用:

      <a href="" ng-click="$$prevSibling.action()">Invoke the Directive Action</a>
      

      要在控制器范围内调用方法,您需要指定使用&amp;,正如@ganaraj 已经演示的那样:

      <content-presenter controller-action="action()">
      

      然后在你的指令中:

      scope: { controllerAction: '&' },
      template: ... +
         '<button ng-click="controllerAction()">Trigger Ctrl action()</button>' ...
      

      Plunker


      使用 ng-repeat(请参阅 Samuel 的评论),每个项目都会创建嵌入范围的子范围。在下图中,我只显示了一个item 以保持图片更小。反转 $$prevSibling 的 $$nextSibling 棕色箭头。

      因此,从 ng-repeat 子作用域到隔离作用域上定义的方法 action() 的技巧是

      <div ng-repeat="item in items" ng-click="$parent.$$prevSibling.action()">
      

      Angular v1.3+ 更新

      从 Angular v1.3 开始,transcluded 作用域现在是指令的isolate 作用域的子对象——它们不再是兄弟。所以要从嵌入范围到隔离范围,请使用$parent

      使用 ng-repeat,每个项目仍然创建一个被嵌入范围的子范围:

      但是要从 ng-repeat 子范围中访问在隔离范围上定义的方法 action(),我们现在使用

      <div ng-repeat="item in items" ng-click="$parent.$parent.action()">
      

      【讨论】:

      • 干杯,成功了。但是,我发现它在ng-repeat 中不起作用(我假设因为每个项目都没有从控制器继承$scope。无论如何每个项目都可以访问$$prevSibling?我已经更新了以上Plunkr举个例子。
      • 太棒了,就像一个魅力!感谢您的图表,非常有用。
      • 您知道是否可以在视图代码中为$parent 链定义一个有意义的名称?类似ng-let="isolateScope = $parent.$parent"
      【解决方案3】:

      据我了解,将ng-repeat 添加到元素会创建一个新范围,以便正确绑定重复内容。您可能需要在该链中添加一个 $parent,例如 $parent.$$nextSibling,以便升级到与指令的隔离范围相邻的级别。

      【讨论】:

        猜你喜欢
        • 2013-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-18
        • 1970-01-01
        • 1970-01-01
        • 2018-11-01
        相关资源
        最近更新 更多