Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Events 减少AngularJS中动态菜单中的事件?_Events_Angularjs_Menu_Watch - Fatal编程技术网

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>