具有隔离作用域的 AngularJS 指令 - 我真的必须在任何地方调用$parent
AngularJS directive with isolate scope - do I really have to call $parent everywhere?
我有一个角度.js指令来创建按钮(悬停类,左右图标等(。我通过scope: { uiButtonIconLeft: '@', uiButtonIconRight: '@' }
使用按钮的左右图标的自动绑定,以便我可以将这些值绑定到父范围中的数据。但是,这会导致angularjs创建一个"隔离"作用域,这意味着在这种情况下使用我的指令不起作用:
<div ng-controller='someController'>
<a ng-repeat='thing in things'
ui-button
ui-button-icon-left='{{thing.icon}}'
ng-click='someMethodTheControllerPutOnTheScope(thing.id)'
>
I don't work, don't bother clicking me
</a>
</div>
相反,我必须这样做:
<div ng-controller='someController'>
<a ng-repeat='thing in things'
ui-button
ui-button-icon-left='{{thing.icon}}'
ng-click='$parent.someMethodTheControllerPutOnTheScope($parent.thing.id)'
>
Holy leaky abstractions, Batman, it works!
</a>
</div>
我的问题是:这是惯用语吗?应该是这样的吗?我做错了吗?我们的英雄能否清除其标记中多余的、重复的、烦人的额外$parent.<whatever>
?
编辑
我为我的按钮"小部件"确定的答案是避免使用隔离范围,并通过attributes.$observe(...)
观察左右图标的属性值,而不是通过范围绑定。
有一种方法可以在不使用显式作用域的情况下做到这一点,如果你正在编写一个不专门处理作用域中元素的指令,最好这样做:
function MyDirective () {
return {
link: function (scope, iElement, iAttrs) {
iAttrs.$observe("uiButtonLeft", function (val) {
if (val) {
iElement.attr(src, val); // whatever you want to do
}
});
}
}
.
<img ui-button ui-button-left="{{item.leftBtn}}"></img>
有时使用{{val}}
会变得很麻烦,无论是干净的代码,还是您可能还想更改val
。这是您可以做到的。
function MyDirective () {
return {
link: function (scope, iElement, iAttrs) {
iAttrs.$observe("uiButtonLeft", function (val) {
scope.$watch(val, function (valInScope) {
if (valInScope) {
iElement.attr(src, valInScope); // whatever you want to do
// the following statement updates the value in scope
// it's kinda weird, but it works.
scope.$apply(val + "= Hello"); // if you are out of angularjs, like jquery event
scope.$eval(val + = "Hello"); // if you are in angualrjs
// $apply can handle string, it's like ngClick
// you use in templates. It updates the value correctly.
}
}
});
}
}
.
<img ui-button ui-button-left="item.leftBtn"></img>
@
仅适用于本地范围属性。 请尝试&
,这允许您在父范围的上下文中执行表达式。
引自 http://docs.angularjs.org/guide/directive
&
或&attr
- 提供一种在上下文中执行表达式的方法 父范围。如果未指定属性名称,则属性名称 假定与本地名称相同。给定<widget my-attr="count = count + value">
和 小部件 的作用域定义:{ localFn:'&myAttr' }
,则隔离范围属性localFn
将指向count = count + value
表达式的函数包装器。经常 希望通过表达式从隔离范围传递数据 对于父范围,这可以通过传递本地映射来完成 变量名称和值到表达式包装器 FN 中。例如 如果表达式increment(amount)
那么我们可以指定amount
通过将localFn
称为localFn({amount: 22})
来的值
约翰·林德奎斯特(John Lindquist(在他的网站上很好地报道了这一点 egghead.io 视频的第17、18和19页。
我明白你想做什么。在您的指令中,只需配置隔离范围以通过 ng-click 属性映射到您想要在父级上的函数。
scope: {
uiButtonIconLeft: '@',
uiButtonIconRight: '@',
clicky: '&ngClick'
}
如果您希望指令使用隔离作用域,并且希望从 HTML/标记中的同一元素调用在父/控制器作用域上定义的方法,则可以使用 $parent。
通常,您不必在 ng-repeat 中使用$parent,因为 ng-repeat 通常会创建一个子作用域,该子作用域通常继承自父/控制器作用域。 因此,在 ng-repeat 中调用方法会沿着原型链一直到父范围来查找该方法。
由于您的指令创建了一个隔离作用域,因此每个 ng-repeat 迭代都强制使用相同的隔离作用域,而不是它通常使用的作用域,因为它们是在同一元素上定义的。 获取在父作用域(从 HTML(上定义的方法的唯一方法是使用 $parent,因为没有原型链可以从隔离作用域遵循。
我们编写的任何自定义指令都需要记录创建哪种作用域。 例如,Angular 文档指示哪些指令会创建新作用域。 有关此内容的更多讨论,请参阅有关此答案的评论:https://stackoverflow.com/a/14345214/215945
另一个选项是将指令更改为不使用隔离作用域,并使用属性来指示指令应检查哪些作用域属性。
- HackReactor,编码窗口现在可以访问一个名为“”的对象;招生;使用名为“;showApp”;.调用此方法时不带任
- 在 JavaScript 中捕获调用方的范围
- 在HTML中嵌套引号>JavaScript>WebForms或如何在JavaScript方法中调用.NET方
- Firefox弹出窗口“;这个网页被重定向到一个新的位置“;在每个requestPromise ajax调用上,有什么方
- 您可以从方法外部识别事件的调用方吗
- 访问外部调用方函数参数
- 在JavaScript中查找调用方脚本
- 事件调用方似乎无法正常工作
- JS - 无法在自定义事件的处理程序中将其指向调用方
- 获取模式调用方
- 流星,如何将回调和错误传递给调用方方法
- 我怎么知道谁是 js 函数的调用方
- 如果被调用方被定义为变量,JavaScript 函数能否知道调用它的内容
- 获取被调用方之一的 Function.Arguments.Arguments
- 如何知道谁是AngularJS中的调用方函数
- 返回调用方数据值的 jQuery 函数
- 从 Template.tmpl.helpers() 调用 Iron-Router RouteController 中的方
- 如何将数据传递到调用方页面
- Google Apps 脚本查找函数调用方 ID
- SignalR - 不要在 javascript 中处理来自当前调用方的通知