Access 指令的作用域与嵌入的内容隔离 [英] Access directive's isolate scope from within transcluded content

查看:48
本文介绍了Access 指令的作用域与嵌入的内容隔离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定这是否真的可能,但我本质上想要一个相反的&"在 AngularJS 中隔离作用域.这是一个 Plunkr 来演示.

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

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

<!-- 指令--><div some-custom-directive><!-- 按钮 1 调用控制器范围内的方法--><button id="button1" ng-click="invoke1()">从控制器调用</button><!-- 按钮 2 为自定义指令调用隔离作用域上的方法--><button id="button2" ng-click="invoke2()">从隔离范围调用</button>

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

更新

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

解决方案

尽管可能,我提出的解决方案是一个 hack,因为它使用了作用域内部变量 $$prevSibling.

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

所以,这个 hack 会起作用:

<a href="" ng-click="$$prevSibling.action()">调用指令动作</a>

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

然后在您的指令中:

scope: { controllerAction: '&'},模板: ... +'<button ng-click="controllerAction()">触发Ctrl action()</button>'...

Plunker

<小时>

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

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

<小时>

Angular v1.3+ 的更新:

从 Angular v1.3 开始,嵌入的作用域现在是指令的隔离作用域的子级 –他们不再是兄弟姐妹.因此,要从嵌入范围转到隔离范围,请使用 $parent.

使用 ng-repeat,每一项仍然会创建一个被嵌入作用域的子作用域:

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

I'm not sure if this is actually possible, but I'm essentially wanting a reverse of the '&' isolate scope in AngularJS. Here is a Plunkr to demonstrate.

Basically, I have a custom directive set up that delivers some reusable HTML. It makes use of ng-transclude to allow some external content to be rendered within it. However, I have found a situation where I would like to access a function that has been set up on the isolate scope for the directive, from within the transcluded section of code.

So essentially I have something that looks like:

<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>

Does anyone know if this is indeed possible?

Update

As per @Mark Rajcok's answer, the $$prevSibling found on the $scope can be used to access the isolate scope of the directive from within the transcluded content. However, I have updated the above Plunkr to attempt this from within an ng-repeat directive, which does not work. I am assuming the items within that repeat do not inherit the scope.

解决方案

Although possible, the solution I present is a hack, as it uses a scope internal variable, $$prevSibling.

Inside your transcluded content, you are inside the transcluded scope. The directive's isolate and transcluded scopes are siblings. To get from the transcluded scope to the isolate scope, you can use $$prevSibling. (To get from the isolate scope to the transcluded scope, you can use $$nextSibling.)

So, this hack will work:

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

To call a method on the controller scope, you need to specify that using & as @ganaraj already demonstrated:

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

Then in your directive:

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

Plunker


With ng-repeat (see Samuel's comment), each item creates a child scope of the transcluded scope. In the picture below, I only show one item to keep the picture smaller. Reverse the $$nextSibling brown arrow for $$prevSibling.

So the hack to get to method action() defined on the isolate scope from an ng-repeat child scope is

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


Update for Angular v1.3+:

Since Angular v1.3, the transcluded scope is now a child of the directive's isolate scope – they are no longer siblings. So to get from the transcluded scope to the isolate scope, use $parent.

With ng-repeat, each item still creates a child scope of the transcluded scope:

But to get to method action() defined on the isolate scope from an ng-repeat child scope, we now use

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

这篇关于Access 指令的作用域与嵌入的内容隔离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆