Access指令的隔离范围来自已转换的内容

Sam*_*ade 16 javascript html5 angularjs angularjs-directive angularjs-scope

我不确定这是否真的可行,但我基本上想要改变AngularJS中的'&'隔离范围.这是一个要展示的Plunkr.

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

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

<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>
Run Code Online (Sandbox Code Playgroud)

有谁知道这确实可能吗?

更新

按@马克Rajcok的回答中,$$prevSibling发现了$scope可以用来从transcluded内容中访问该指令的分离范围.但是,我已经更新了上面的Plunkr,以便在一个ng-repeat指令中尝试这个,这个指令不起作用.我假设重复内的项目不继承范围.

Mar*_*cok 20

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

在您的被抄送的内容中,您位于被抄送的范围内.该指令的隔离和转换范围是兄弟姐妹.要从transcluded范围到隔离范围,您可以使用$$prevSibling.(要从隔离范围到transcluded范围,您可以使用$$nextSibling.)

所以,这个黑客会起作用:

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

要在控制器作用域上调用方法,您需要指定使用&已经演示的@ganaraj:

<content-presenter controller-action="action()">
Run Code Online (Sandbox Code Playgroud)

然后在你的指令中:

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

Plunker


使用ng-repeat(参见Samuel的评论),每个项目都会创建一个转换范围的子范围.在下面的图片中,我只展示了一张item让图片更小的图片.反转$$ prevSibling的$$ nextSibling棕色箭头.

在此输入图像描述

因此,action()从ng-repeat子范围获取在隔离范围上定义的方法的hack 是

<div ng-repeat="item in items" ng-click="$parent.$$prevSibling.action()">
Run Code Online (Sandbox Code Playgroud)

Angular v1.3 +的更新:

从Angular v1.3开始,transcluded范围现在是指令的隔离范围的子代 - 它们不再是兄弟姐妹.因此,要从transcluded范围到隔离范围,请使用$parent.

使用ng-repeat,每个项目仍会创建转换范围的子范围:

在此输入图像描述

但是为了action()从ng-repeat子范围获得隔离范围上定义的方法,我们现在使用

<div ng-repeat="item in items" ng-click="$parent.$parent.action()">
Run Code Online (Sandbox Code Playgroud)