修改具有 ng-repeat 和属性集运行时的指令模板的 DOM
Modify DOM of a template of a directive that have an ng-repeat with attribute set runtime
我必须将 css class 添加到在 ng-repeat 中创建的 dom 的元素。只有在验证条件时才必须添加 css class。根据 ng-repeat 中处理的项目计算值的属性检查条件。
我让你看代码更清楚
这是我的指令:
intranet
.directive('emitLastRepeaterElement', function () {
return function (scope) {
if (scope.$last) {
scope.$emit('LastRepeaterElement');
}
};
})
.directive('scVerticalMenu', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'Scripts/Angular/Directives/VerticalMenu/verticalMenu.html',
scope: {
internalSiteMenu: '=ngModel' //two-way data-binding
},
link: function (scope, element, attrs) {
scope.$on('LastRepeaterElement',
function () {
//Recupero l'ultimo link del menu interno di livello 2 che non abbia figli
//(L'ultimo link non deve avere il bordo nero inferiore)
var level2 = element.find("li[role=menuitem]:has(.level2):last");
var level3 = element.find("li[role=menuitem]:has(.level3)");
if ($(level2).next(level3).length == 0) {
$(level2).addClass('last');
}
});
}
}
});
这里是模板:
<ul class="level1 static" tabindex="0" role="menu" style="position: relative; width: auto; float: left;">
<li role="menuitem" class="static" style="position: relative;" ng-repeat="menu in internalSiteMenu" emit-last-repeater-element>
<a class="level{{ menu.Level }} static" href="{{ menu.Url }}" tabindex="-1">{{ menu.Name }}</a>
</li>
</ul>
我在这里,在 Whosebug 中找到了一个解决方案。当我执行 ng-repeat 的最后一个循环时,我发出一个事件。它部分起作用。我进入 link
函数,但找不到对象。我调试了。
看起来在 link
函数内部,锚点的 class 仍然是 class="level{{ menu.Level }}"
而不是 class="level2"
或 class="level3"
我认为我的做法是错误的。也许我必须找到另一个解决方案。
你有什么建议吗?
谢谢
更新
确切地说,我有一个具有更多级别的菜单:
menu
item 1
item 1.2
item 1.3
item 1.4
item 2
item 2.1
item 2.2
item 3
我想为每个级别的每个最后一项添加一个 class。所以在我的示例中,我想在此处添加 class:
menu
item 1
item 1.2
item 1.3
item 1.4 <-- addClass: last of item 1
item 2
item 2.1
item 2.2 <-- addClass: last of item 2
item 3 <-- addClass: last of menu
更新 2
我在 _layout.cshtml 页面中使用指令。这样:
<div ng-controller="menuController" ng-init="getMenu">
<sc-vertical-menu ng-model="siteMenu"></sc-vertical-menu>
</div>
menuController调用后端获取menù并将结果放入$scope.siteMenu
查看 fiddle:http://jsfiddle.net/umL03t49/1/
只需使用您的 scVerticalMenu
控制器检测哪些项目是最后的:
intranet
.directive('scVerticalMenu', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'Scripts/Angular/Directives/VerticalMenu/verticalMenu.html',
scope: {
internalSiteMenu: '=ngModel' //two-way data-binding
},
link: function (scope, element, attrs) {
for (var i = 0; i < scope.internalSiteMenu.length - 1; i++) {
if (scope.internalSiteMenu[i].level > scope.internalSiteMenu[i + 1].level) {
scope.internalSiteMenu[i].last = true
}
}
scope.internalSiteMenu[scope.internalSiteMenu.length - 1].last = true
}
}
});
然后用ng-class
显示last
class
<ul class="level1 static" tabindex="0" role="menu" style="position: relative; width: auto; float: left;">
<li role="menuitem" class="static" ng-class="{'last': menu.last}" style="position: relative;" ng-repeat="menu in internalSiteMenu">
<a class="level{{ menu.Level }} static" href="{{ menu.Url }}" tabindex="-1">{{ menu.Name }}</a>
</li>
</ul>
我必须将 css class 添加到在 ng-repeat 中创建的 dom 的元素。只有在验证条件时才必须添加 css class。根据 ng-repeat 中处理的项目计算值的属性检查条件。
我让你看代码更清楚
这是我的指令:
intranet
.directive('emitLastRepeaterElement', function () {
return function (scope) {
if (scope.$last) {
scope.$emit('LastRepeaterElement');
}
};
})
.directive('scVerticalMenu', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'Scripts/Angular/Directives/VerticalMenu/verticalMenu.html',
scope: {
internalSiteMenu: '=ngModel' //two-way data-binding
},
link: function (scope, element, attrs) {
scope.$on('LastRepeaterElement',
function () {
//Recupero l'ultimo link del menu interno di livello 2 che non abbia figli
//(L'ultimo link non deve avere il bordo nero inferiore)
var level2 = element.find("li[role=menuitem]:has(.level2):last");
var level3 = element.find("li[role=menuitem]:has(.level3)");
if ($(level2).next(level3).length == 0) {
$(level2).addClass('last');
}
});
}
}
});
这里是模板:
<ul class="level1 static" tabindex="0" role="menu" style="position: relative; width: auto; float: left;">
<li role="menuitem" class="static" style="position: relative;" ng-repeat="menu in internalSiteMenu" emit-last-repeater-element>
<a class="level{{ menu.Level }} static" href="{{ menu.Url }}" tabindex="-1">{{ menu.Name }}</a>
</li>
</ul>
我在这里,在 Whosebug 中找到了一个解决方案。当我执行 ng-repeat 的最后一个循环时,我发出一个事件。它部分起作用。我进入 link
函数,但找不到对象。我调试了。
看起来在 link
函数内部,锚点的 class 仍然是 class="level{{ menu.Level }}"
而不是 class="level2"
或 class="level3"
我认为我的做法是错误的。也许我必须找到另一个解决方案。 你有什么建议吗?
谢谢
更新 确切地说,我有一个具有更多级别的菜单:
menu
item 1
item 1.2
item 1.3
item 1.4
item 2
item 2.1
item 2.2
item 3
我想为每个级别的每个最后一项添加一个 class。所以在我的示例中,我想在此处添加 class:
menu
item 1
item 1.2
item 1.3
item 1.4 <-- addClass: last of item 1
item 2
item 2.1
item 2.2 <-- addClass: last of item 2
item 3 <-- addClass: last of menu
更新 2 我在 _layout.cshtml 页面中使用指令。这样:
<div ng-controller="menuController" ng-init="getMenu">
<sc-vertical-menu ng-model="siteMenu"></sc-vertical-menu>
</div>
menuController调用后端获取menù并将结果放入$scope.siteMenu
查看 fiddle:http://jsfiddle.net/umL03t49/1/
只需使用您的 scVerticalMenu
控制器检测哪些项目是最后的:
intranet
.directive('scVerticalMenu', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'Scripts/Angular/Directives/VerticalMenu/verticalMenu.html',
scope: {
internalSiteMenu: '=ngModel' //two-way data-binding
},
link: function (scope, element, attrs) {
for (var i = 0; i < scope.internalSiteMenu.length - 1; i++) {
if (scope.internalSiteMenu[i].level > scope.internalSiteMenu[i + 1].level) {
scope.internalSiteMenu[i].last = true
}
}
scope.internalSiteMenu[scope.internalSiteMenu.length - 1].last = true
}
}
});
然后用ng-class
显示last
class
<ul class="level1 static" tabindex="0" role="menu" style="position: relative; width: auto; float: left;">
<li role="menuitem" class="static" ng-class="{'last': menu.last}" style="position: relative;" ng-repeat="menu in internalSiteMenu">
<a class="level{{ menu.Level }} static" href="{{ menu.Url }}" tabindex="-1">{{ menu.Name }}</a>
</li>
</ul>