Events 减少AngularJS中动态菜单中的事件?
我构建了一个动态菜单,它也有高亮显示。Events 减少AngularJS中动态菜单中的事件?,events,angularjs,menu,watch,Events,Angularjs,Menu,Watch,我构建了一个动态菜单,它也有高亮显示。现在我遇到了一个问题,路径更改事件的数量随着菜单元素的增加而增加。 当然,这是对菜单的每个元素应用指令的结果 目前,自定义指令是我最薄弱的地方,我不知道如何重构所有这些。 为了注册watch一次,我还尝试将指令放在menu(ul)的根元素中,但仍然坚持访问深层子元素(ul->li->a.href) 以下是指令: app.directive("testdir", function($location) { return { restri
现在我遇到了一个问题,路径更改事件的数量随着菜单元素的增加而增加。
当然,这是对菜单的每个元素应用指令的结果 目前,自定义指令是我最薄弱的地方,我不知道如何重构所有这些。
为了注册watch一次,我还尝试将指令放在menu(ul)的根元素中,但仍然坚持访问深层子元素(ul->li->a.href) 以下是指令:
app.directive("testdir", function($location)
{
return {
restrict: 'A',
link: function(scope, element, attrs, controller) {
scope.$watch(function() { return $location.path(); }, function(path)
{
scope.$parent.firedEvents++;
path=path.substring(1);
if(path === element.children().attr("href").substring(2))
{
element.addClass("activeLink");
}
else
{
element.removeClass("activeLink");
}
})
}
};
和HTML部分:
<ul ng-app="test" ng-controller="MenuCtrl">
<li ng-repeat="link in menuDef" testdir><a href="{{link.url}}">{{link.linkName}}</a></li>
</ul>
整例
如何重构?我累坏了。而且,我正朝着正确的方向前进?我有一种感觉,这件事可以用更简单的方式来完成,但也许我错了。首先,你的
firedEvents
意味着回调调用了多少次,而不是位置实际更改了多少次,而不是“路径更改事件数”
您有20个作用域(如在您的小提琴中)正在监视位置更改,当您单击当前活动链接以外的其他链接时,位置更改,20个作用域中的所有都将看到更改并调用其自己的$watch
回调函数,每次调用回调都会增加您的firedEvents
,因此结果就是您所看到的:计数增加了20
因此,如果您想让firedEvents
计算位置更改了多少时间,您应该移动scope.$parent.firedEvents++如果
,则编码>到中。但是请记住,每次单击都会导致回调函数被调用20次
有很多方法可以达到你们在这里试图达到的效果,我有一个解决方案给你们,根本不需要深入研究指令。给你:
HTML
HTML
-
jsiddle:首先,您的firedEvents
表示回调调用了多少次,而不是位置实际更改了多少次,这不是“路径更改事件数”
您有20个作用域(如在您的小提琴中)正在监视位置更改,当您单击当前活动链接以外的其他链接时,位置更改,20个作用域中的所有都将看到更改并调用其自己的$watch
回调函数,每次调用回调都会增加您的firedEvents
,因此结果就是您所看到的:计数增加了20
因此,如果您想让firedEvents
计算位置更改了多少时间,您应该移动scope.$parent.firedEvents++如果
,则编码>到中。但是请记住,每次单击都会导致回调函数被调用20次
有很多方法可以达到你们在这里试图达到的效果,我有一个解决方案给你们,根本不需要深入研究指令。给你:
HTML
HTML
-
jsFiddle:太好了。谢谢但这种变体有一个缺点,它不监听路径更改,任何其他链接(菜单中不存在)都不会对高亮显示产生影响。看看这里:顺便说一下,我做了一些重构,现在我有一个事件制作人和20个消费者(即li标签),这比imho好多了。它在这里:不幸的是,这一个也有问题。第一个“pathChange”事件发生得太早,而作为一个例子,指令尚未侦听事件。有什么想法吗?:)看来我解决了最后一个问题。不知道这是否正确。下面是:@VirtualVoid One$watch调用看起来确实更好,但每次单击都会调用20个事件处理程序,这对性能不利。我要用更好的解决方案更新我的答案。@Virtualoid更新了我的答案。@Virtualoid我已经更新了小提琴来处理第一个位置更改问题,这很好。谢谢但这种变体有一个缺点,它不监听路径更改,任何其他链接(菜单中不存在)都不会对高亮显示产生影响。看看这里:顺便说一下,我做了一些重构,现在我有一个事件制作人和20个消费者(即li标签),这比imho好多了。它在这里:不幸的是,这一个也有问题。第一个“pathChange”事件发生得太早,而作为一个例子,指令尚未侦听事件。有什么想法吗?:)看来我解决了最后一个问题。不知道这是否正确。下面是:@VirtualVoid One$watch调用看起来确实更好,但每次单击都会调用20个事件处理程序,这对性能不利。我将用更好的解决方案更新我的答案。@Virtualoid更新了我的答案。@Virtualoid我已更新了小提琴以处理第一个位置更改问题
<ul ng-controller="MenuCtrl">
<li ng-repeat="link in menuDef" ng-class="{activeLink: link.isActive}" ng-click="onLinkClick(link)"><a href="{{link.url}}">{{link.linkName}}</a>
</li>
</ul>
app.controller("MenuCtrl", function ($scope, $location) {
var menugen = [];
for (var i = 1; i <= 20; i++) {
menugen.push({
linkName: "Link " + i,
url: "#/url" + i
});
}
$scope.menuDef = menugen;
var activeLink = null;
$scope.onLinkClick = function (link) {
if (activeLink && $scope.activeLink !== link) {
activeLink.isActive = false;
}
link.isActive = true;
activeLink = link;
};
});
app.directive('menu', function ($location) {
return {
restrict: 'A',
controller: function ($scope, $location) {
var links = [];
this.registerLink = function (elem, path) {
links.push({
elem: elem,
path: path
});
};
$scope.$watch(function () {
return $location.path();
}, function (path) {
for (var i = 0; i < links.length; i++) {
if (path === links[i].path) {
links[i].elem.addClass('activeLink');
} else {
links[i].elem.removeClass('activeLink');
}
}
});
}
};
}).
directive("testdir", function () {
return {
restrict: 'A',
require: '^menu',
link: function (scope, element, attrs, controller) {
controller.registerLink(element, scope.link.url.substring(1));
}
};
});
<ul ng-app="test" ng-controller="MenuCtrl" menu>
<li ng-repeat="link in menuDef" testdir>
<a href="{{link.url}}">{{link.linkName}}</a>
</li>
</ul>