Parent/child click relationships in AngularJS directives

旧街凉风 提交于 2019-12-12 03:07:53

问题


I have a custom directive placed on a Kendo UI treeview widget.

It seems to be working fine side-by-side, except that I'm trying to simply display the custom icons next to the tree node which is clicked on (see sample image below).

So my directive is data-toggle-me, placed next to the Kendo k-template directive as follows :

<div class="reports-tree" kendo-tree-view="nav.treeview"             
                    k-options="nav.treeOptions"
                    k-data-source="nav.reportsTreeDataSource"
                    k-on-change="nav.onTreeSelect(dataItem)"  >

      <span class="tree-node" k-template data-toggle-tree-icons>{{dataItem.text}}</span>
  
</div>

and the directive code here inserts some custom icons next to the tree node when a user clicks on that tree node :

 .directive('toggleMe', function ($compile) {
      // Kendo treeview, use the k-template directive to embed a span.
      // Icons appear on Click event. 
      return {
          restrict: 'AE',
          transclude: true,
          template: '<span ng-show="nav.displayIcons" id="myIcons" class="reptIcons" style="display:none;width:50px;align:right;">' +
                ' <a title="add new folder" ng-click="nav.addAfter(nav.selectedItem)"><i class="fa fa-folder-open"></i></a>&nbsp;&nbsp;' +
                '<a title="add report here" ng-click="nav.addBelow(nav.selectedItem)"><i class="fa fa-plus"></i></a>&nbsp;&nbsp;' +
                '<a title="remove" ng-click="nav.remove(nav.selectedItem)"><i class="fa fa-remove"></i></a>&nbsp;&nbsp;' +
                '<a title="rename" onclick="showRename(this);"><i class="fa fa-pencil"></i></a>' +
              '</span>',
          link: function (scope, elem, attrs) {              
              var icons = elem.find("#myIcons");
              elem.on('click', function (e) {                  
                  $('.reptIcons').css('display', 'none');
                  icons.css("display", "inline");
                  icons.css("margin-left", "5px");
              });              
          }
      }
    })

My biggest problem at this point is getting the icons to appear on the treenode which is clicked on. Then once the user clicks on a different node, the icons will only render again on the newly-clicked node.

This fiddle represents a partially-working example but the icons are appearing on every single treenode - click tree item to show icons

**** UPDATED TREE IMAGE - All child nodes now show icons (not what I want) ****


回答1:


I'm not sure to understand your issue, you should try to reduce the code to the minimum and have a snippet/jsfiddle that works.

If all you want is not trigger click events when $scope.disableParentClick is set to true, simply add

elem.on('click', function (e) {
  // Do not execute click event if disabled
  if (!$scope.disableParentClick) { return; }
  ...
});

Now that seems all not very angular friendly to me. You should externalize your HTML in either the template or templateUrl of your directive, potentially adding to it a ng-if="displayTemplate" which would only display the node when a click would set $scope.displayTemplate = true;

Also, instead of listening for click events this way, you should use the ng-click directive. Everything is doable with directives. I can give more information when you better understand your problem: I suspect you are not approaching it the right way.

UPDATE: if all you want is display the icons list of the clicked element, you could do it way easier. You actually don't need the toggle-me directive, but even if you keep it you can solve all your troubles the angular-way, which is by using ng-click, ng-repeat, etc. Please have a look at the following jsFiffle to see one way of doing that. There are many other ways, but really try using ng-click to avoid troubles:

http://jsfiddle.net/kau9jnoe/




回答2:


Events in the DOM are always bubbling up. That is a click on a link would trigger an onclick handler on every element up the hierarchy, e.g. also the body element. After all the click happened within body.

The same is true for your directive. Any click within your element triggers its event handler. To circumvent this either attach the event handler somewhere else or ignore clicks from the links.

The event object has a target property that tells you what element initiated the event. So you could do something like this:

elem.on('click', function (e) { 
 if (e.target.nodeName.toLowerCase() == 'a') return; //ignore click on links


来源:https://stackoverflow.com/questions/28752567/parent-child-click-relationships-in-angularjs-directives

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