Parent/child 单击 AngularJS 指令中的关系
Parent/child click relationships in AngularJS directives
我在 Kendo UI 树视图小部件上放置了一个自定义指令。
它似乎并排工作正常,除了我试图简单地在单击的树节点旁边显示自定义图标(参见下面的示例图片)。
所以我的指令是 data-toggle-me
,放在 Kendo k-template
指令旁边,如下所示:
<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>
当用户 clicks
在该树节点上时,此处的指令代码会在树节点旁边插入一些自定义图标:
.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> ' +
'<a title="add report here" ng-click="nav.addBelow(nav.selectedItem)"><i class="fa fa-plus"></i></a> ' +
'<a title="remove" ng-click="nav.remove(nav.selectedItem)"><i class="fa fa-remove"></i></a> ' +
'<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");
});
}
}
})
此时我最大的问题是让图标出现在被点击的树节点上。然后一旦用户点击不同的节点,图标将只在新点击的节点上再次呈现。
这个 fiddle 代表一个部分工作的示例,但图标出现在每个树节点上 - click tree item to show icons
**** 更新的树形图像 - 所有子节点现在都显示图标(不是我想要的)****
我不确定是否理解您的问题,您应该尝试将代码减少到最少并使 snippet/jsfiddle 有效。
如果您想要的只是在 $scope.disableParentClick
设置为 true 时不触发点击事件,只需添加
elem.on('click', function (e) {
// Do not execute click event if disabled
if (!$scope.disableParentClick) { return; }
...
});
现在看来对我来说都不是很 angular 友好。您应该在指令的 template
或 templateUrl
中将 HTML 外部化,可能会向其添加一个 ng-if="displayTemplate"
,它只会在点击设置时显示节点 $scope.displayTemplate = true;
此外,您应该使用 ng-click
指令,而不是以这种方式监听点击事件。一切都可以通过指令来实现。当您更好地理解您的问题时,我可以提供更多信息:我怀疑您没有以正确的方式处理它。
更新:如果你只想显示被点击元素的图标列表,你可以做得更容易。您实际上不需要 toggle-me
指令,但即使保留它,您也可以通过 angular 方式解决所有问题,即使用 ng-click
、ng-repeat
等。请查看以下 jsFiffle 以了解一种方法。还有很多其他的方法,但真的尝试使用 ng-click 来避免麻烦:
DOM 中的事件总是不断涌现。也就是说,单击 link 会在 每个 元素上触发 onclick
处理程序,例如还有 body
元素。所有点击都发生在 body
.
内
您的指令也是如此。元素中的任何单击都会触发其事件处理程序。要避免这种情况,要么将事件处理程序附加到其他地方,要么忽略来自 link 的点击。
事件对象有一个 target
属性 告诉您哪个元素启动了事件。所以你可以这样做:
elem.on('click', function (e) {
if (e.target.nodeName.toLowerCase() == 'a') return; //ignore click on links
我在 Kendo UI 树视图小部件上放置了一个自定义指令。
它似乎并排工作正常,除了我试图简单地在单击的树节点旁边显示自定义图标(参见下面的示例图片)。
所以我的指令是 data-toggle-me
,放在 Kendo k-template
指令旁边,如下所示:
<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>
当用户 clicks
在该树节点上时,此处的指令代码会在树节点旁边插入一些自定义图标:
.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> ' +
'<a title="add report here" ng-click="nav.addBelow(nav.selectedItem)"><i class="fa fa-plus"></i></a> ' +
'<a title="remove" ng-click="nav.remove(nav.selectedItem)"><i class="fa fa-remove"></i></a> ' +
'<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");
});
}
}
})
此时我最大的问题是让图标出现在被点击的树节点上。然后一旦用户点击不同的节点,图标将只在新点击的节点上再次呈现。
这个 fiddle 代表一个部分工作的示例,但图标出现在每个树节点上 - click tree item to show icons
**** 更新的树形图像 - 所有子节点现在都显示图标(不是我想要的)****
我不确定是否理解您的问题,您应该尝试将代码减少到最少并使 snippet/jsfiddle 有效。
如果您想要的只是在 $scope.disableParentClick
设置为 true 时不触发点击事件,只需添加
elem.on('click', function (e) {
// Do not execute click event if disabled
if (!$scope.disableParentClick) { return; }
...
});
现在看来对我来说都不是很 angular 友好。您应该在指令的 template
或 templateUrl
中将 HTML 外部化,可能会向其添加一个 ng-if="displayTemplate"
,它只会在点击设置时显示节点 $scope.displayTemplate = true;
此外,您应该使用 ng-click
指令,而不是以这种方式监听点击事件。一切都可以通过指令来实现。当您更好地理解您的问题时,我可以提供更多信息:我怀疑您没有以正确的方式处理它。
更新:如果你只想显示被点击元素的图标列表,你可以做得更容易。您实际上不需要 toggle-me
指令,但即使保留它,您也可以通过 angular 方式解决所有问题,即使用 ng-click
、ng-repeat
等。请查看以下 jsFiffle 以了解一种方法。还有很多其他的方法,但真的尝试使用 ng-click 来避免麻烦:
DOM 中的事件总是不断涌现。也就是说,单击 link 会在 每个 元素上触发 onclick
处理程序,例如还有 body
元素。所有点击都发生在 body
.
您的指令也是如此。元素中的任何单击都会触发其事件处理程序。要避免这种情况,要么将事件处理程序附加到其他地方,要么忽略来自 link 的点击。
事件对象有一个 target
属性 告诉您哪个元素启动了事件。所以你可以这样做:
elem.on('click', function (e) {
if (e.target.nodeName.toLowerCase() == 'a') return; //ignore click on links