父指令中的 angularjs 函数没有从嵌入的 html 中调用 [英] angularjs function in parent directive not getting called from transcluded html
问题描述
我使用 angualrjs 指令创建了一个类似功能的下拉列表,该指令在某种程度上起作用,但不是我预期的正确方式.
以下是我面临的问题.
- 下拉列表的对齐方式对于静态来说是正确的,但对于动态来说却不是
- 我无法选择任何选项列表,因为我在父指令中定义的
getValue
函数不是从被嵌入的指令中调用的
谁能告诉我一些解决方案
我的代码如下
静止的<grant-parent ng-model="grand1"><parent label="Parent1" value="12"><child value="56" label="Child1">Child1</child><child value="57" label="Child2">Child2</child></父母><parent label="Parent1" value="13"><child value="58" label="Child3">Child3</child><child value="59" label="Child4">Child4</child></父母></grant-parent>动态的<grant-parent ng-model="grand2"><parent ng-repeat="parent in data" label="{{parent.parentName}}" value="{{parent.parentId}}"><child ng-repeat="child in parent.childrens" label="{{child.name}}" value="{{child.id}}">{{child.name}}</child></父母></grant-parent>
Transclusion 和 ng-repeat
让我很头疼,我认为这会很有挑战性,但解决方案很简单:
从链接函数中移除 DOM 操作并在模板中进行嵌入!
即<div ng-transclude></div>
在 parent
的模板中并删除这一行: elm.find('div').replaceWith(transclude())
.
分叉的 plunk:http://plnkr.co/edit/UGp6D29yxnu0uJwD1BM2?p=preview一个>
<小时>现在标记出来的有点不同,包装器
<li>
,例如如:<b><a href='#' ng-click='getValue(optGroupLabel,optGroupValue)'>{{optGroupLabel}}<span class='value'>{{optGroupValue}}</span>;</a></b><div ng-transclude></div><!-- div 现在在 li 内-->
这在 plunker 中有效,但标记仍然无效( 在
最好的解决方案是将孩子们包裹在他们自己的
中,即:
<b><a href='#' ng-click='getValue(optGroupLabel,optGroupValue)'>{{optGroupLabel}}<span class='value'>{{optGroupValue}}</span>;</a></b><ul ng-transclude></ul><!-- div 替换为 ul -->
这在 plunk 中不能正常工作,但应该可以通过一些 CSS 调整来工作.
<小时>关于 getValue
您弄错了隔离作用域和嵌入的工作方式.grandParent
指令在其隔离范围内定义了 getValue
方法.被嵌入的东西(parent
和 child
指令)得到 outer 作用域,即 MainCtrl
的作用域.一个解决方案是将 getValue()
移动到 MainCtrl
.
更好的解决方案是将回调传递给祖父母的后代,例如作为 scope: {assignValue: '&'}
.但是这个解决方案不能在当前形式的代码中实现,因为祖父母不直接包含它的孩子,所以它不能向他们传递参数.
最终解决方案 - 从注释中复制:将 getValue
移动到 GrandParent 的 controller,让父级和子级需要祖父级并调用该函数.请参阅 http://plnkr.co/edit/pS9SspLaoPlqoWMYr8I0?p=preview
I have created a dropdown list like feature using angualrjs directive, The directive is working somewhat but not in correct way I expected.
Following are the issues which I am facing.
- The drop-down list alignment is correct for static but not for dynamic
- I am not able to select any of the option list since
getValue
function which I have defined in the parent directive is not been invoked from the trancluded directive
Can anyone please tell me some solution for this
My code is as given below
<div ng-controller="MainCtrl">
Static
<grant-parent ng-model="grand1">
<parent label="Parent1" value="12">
<child value="56" label="Child1">Child1</child>
<child value="57" label="Child2">Child2</child>
</parent>
<parent label="Parent1" value="13">
<child value="58" label="Child3">Child3</child>
<child value="59" label="Child4">Child4</child>
</parent>
</grant-parent>
Dynamic
<grant-parent ng-model="grand2">
<parent ng-repeat="parent in data" label="{{parent.parentName}}" value="{{parent.parentId}}">
<child ng-repeat="child in parent.childrens" label="{{child.name}}" value="{{child.id}}">{{child.name}}</child>
</parent>
</grant-parent>
</div>
Transclusion and ng-repeat
have caused me headaches, and I thought it would be challenging, but the solution proves quite simple:
Remove the DOM manipulation from your link function and do the transclusion in the template!
I.e. <div ng-transclude></div>
in the template of the parent
and remove this line: elm.find('div').replaceWith(transclude())
.
Forked plunk: http://plnkr.co/edit/UGp6D29yxnu0uJwD1BM2?p=preview
Now the markup comes out a bit different, the wrapper <div>
still exists. Although there seems to be no visual difference, this may not be what you want. I do not think there is a sane way to get around this, so I would suggest altering the layout a bit: Why don't you place the children inside the parent <li>
, e.g. as:
<li>
<b><a href='#' ng-click='getValue(optGroupLabel,optGroupValue)'>{{optGroupLabel}}<span class='value'>{{optGroupValue}}</span></a></b>
<div ng-transclude></div><!-- the div is now inside the li -->
</li>
This works in the plunker, but the markup is still invalid (<li>
within <div>
).
The best solution is to wrap the children in their own <ul>
, i.e.:
<li>
<b><a href='#' ng-click='getValue(optGroupLabel,optGroupValue)'>{{optGroupLabel}}<span class='value'>{{optGroupValue}}</span></a></b>
<ul ng-transclude></ul><!-- The div is replaced with ul -->
</li>
This does not work in the plunk as it is, but should work with a little CSS tweaking.
Concerning getValue
You have gotten wrong how isolated scopes and transclusion work. The grandParent
directive defines the getValue
method in its isolated scope. The transcluded things (the parent
and child
directives) get the outer scope, i.e. the scope of the MainCtrl
. A solution is to move getValue()
to the MainCtrl
.
A better solution would be to pass a callback to the descendants of the grandparent, e.g. as scope: { assignValue: '&' }
. But this solution cannot be implemented for the code in its current form because the grandparent does not directly include its children, so it cannot pass arguments to them.
The final solution - copied from the comments: move getValue
to the controller of grandParent, have the parent and children require the grandparent and call that function. See http://plnkr.co/edit/pS9SspLaoPlqoWMYr8I0?p=preview
这篇关于父指令中的 angularjs 函数没有从嵌入的 html 中调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!