angularjs function in parent directive not getting called from transcluded html

与世无争的帅哥 提交于 2019-12-11 07:15:50

问题


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

PLUNKER

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

回答1:


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



来源:https://stackoverflow.com/questions/29426932/angularjs-function-in-parent-directive-not-getting-called-from-transcluded-html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!