我正在尝试使用Angular实现下拉菜单,如果用户点击链接1,则应显示链接1的内容。我的指示如下:
这是我的AngularJS代码:
angular.module("myApp", [])
.controller("testCtrl", function ($scope) {})
.directive("mobileMenu", function () {
return {
controller: function ($scope) {
this.menuLinks = [];
this.menuItems = [];
this.addMenuLink = function (l) {
this.menuLinks.push(l);
};
this.addMenuItem = function (m) {
this.menuItems.push(m);
};
// Function to close all other menu items if they are open.
// This is because only one menu item can be active at a time
this.closeOthers = function (selectedMenuLink) {
angular.forEach(this.menuLinks, function (l) {
if (l !== selectedMenuLink) {
l.selected = false;
}
});
angular.forEach(this.menuItems, function (m) {
if (selectedMenuLink.target == m.menuId) {
m.test = true;
} else {
m.test = false;
}
});
};
}
};
}).directive("menuLink", function () {
return {
require: "^mobileMenu",
scope: {},
link: function(scope, element, attrs, menuController) {
scope.selected = false;
menuController.addMenuLink(scope);
scope.$watch('selected', function(newValue, oldValue) {
if (oldValue === newValue) {return};
if (newValue) {
scope.target = angular.element(element[0].children[0]).attr("data-menu");
menuController.closeOthers(scope);
}
});
}
};
}).directive("menuItem", function () {
return {
require: "^mobileMenu",
scope: true,
link: function (scope, element, attrs, menuController) {
scope.test = false;
scope.menuId = attrs.id;
menuController.addMenuItem(scope);
scope.$watch('test', watchLink);
scope.$watch(attrs.collapse, watchLink);
scope.$watch(function () {
return scope.test;
}, watchLink);
var watchLink = function (newValue, oldValue) {
// Initializing for the first time, do nothing
if (newValue === oldValue) return;
// If the collapse attribute has a true value, collapse this element
if (newValue) {
collapse();
} else {
expand();
}
};
// Helper function to collapse the element
var collapse = function () {
element.css({
height: "0px"
});
};
// Helper function to show the element
var expand = function () {
element.css({
height: "200px"
});
};
}
};
});
这是我的HTML代码:
<div ng-app="myApp" ng-controller="testCtrl">
<div mobile-menu>
<ul>
<li menu-link>
<a href="#" ng-click="selected = !selected" ng-class="{'expanded' : selected, 'collapsed' : !selected}" data-menu="menu0">Link 1</a>
</li>
<li menu-link>
<a href="#" ng-click="selected = !selected" ng-class="{'expanded' : selected, 'collapsed' : !selected}" data-menu="menu1">Link 2</a>
</li>
</ul>
<div id="menu0" ng-class="{'expanded' : test, 'collapsed' : !test}" menu-item collapse="!test">
<p class="text">First Menu</p>
</div>
<div id="menu1" ng-class="{'expanded' : test, 'collapsed' : !test}" menu-item collapse="!test">
<p class="promo-text">Second Menu</p>
</div>
</div>
我遇到一个问题,如果单击菜单链接#1,应该更新相应的菜单项#1的scope.test值,并且应该触发其“范围监视”,但事实并非如此。如果示波器监视触发了watchLink功能,那么我希望菜单项#1的高度为200px。
我还附上了一个jsfiddle示例: http://jsfiddle.net/EmwBP/28/
如果查看浏览器控制台工具,相应的菜单项ng-class将始终根据其scope.test值进行更新。然而,即使我设置了3个不同的范围观察者,也没有一个被触发。我也使用ng-class指令只是为了表明scope.test值确实已更新,并将在最终实现中删除。
通常情况下,我会将菜单项指令作为菜单链接的子项,但我有一个要求,我现在必须放置菜单项,以实现推送的下拉效果它下面的元素。
非常感谢您的意见和协助
答案 0 :(得分:1)
使用 menuLink
在scope: {}
中创建新的隔离范围。因此,您在该范围内设置的任何范围变量(如selected
)仅在该范围内可用,并且不会传播到兄弟范围或父范围。
您需要做的是使用 menuLink
去隔离scope: true
范围。
这不是问题。问题是在定义watchLink
之前使用watchLink
。修复触发{{1}}的位置:http://jsfiddle.net/EmwBP/31/