我想做一个指令,它会使Angular UI-Router声明信息,并根据它创建一个导航栏。现在我们会采取什么正确的方式?
a)
创建具有$state
依赖关系的NavController,获取状态信息并将其转换为合适的JS数组,然后通过属性将此数组传递给指令并在那里执行DOM操作。
b)
创建一个具有$state
依赖关系的NavDirective,并在其中完成所有工作(状态信息转换和DOM操作)。
什么是好的做法?
现在我有以下内容:
app.directive('navigation', ['$parse', '$compile', function ($parse, $compile) {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attrs) {
scope.selectedNode = null;
scope.$watch(attrs.menuData, function (val) {
var template = angular.element(
'<ul class="nav navbar-nav">'
+ '<li ng-repeat="node in ' + attrs.menuData + '" active-tab="{{node.href}}">'
+ '<a ui-sref="{{node.state}}"><b>{{node.text}}</b></a>'
+ '</li>'
+ '</ul>'
);
var linkFunction = $compile(template);
linkFunction(scope);
element.html(null).append( template );
}, true);
}
};
}]);
app.controller('NavigationController', ['$scope', '$state', function ($scope, $state) {
var menu = [];
var states = $state.get();
_.each(states, function(state, key) {
if(!_.isObject(state) || _.has(state, 'abstract') || _.has(state, 'parent')) {
return;
}
var object = {
text: _.has(state.data, 'title') ? state.data.title : '(no title)',
state: state.name,
href: state.url
}
menu.push(object);
});
$scope.menu = menu;
}]);
答案 0 :(得分:0)
通常不应使用控制器来执行DOM操作。
来自角度开发者指南:
https://docs.angularjs.org/guide/controller
不要使用控制器:
操纵DOM - 控制器应仅包含业务逻辑。将任何表示逻辑放入控制器会显着影响其可测试性。 Angular对大多数情况和指令进行数据绑定以封装手动DOM操作。
答案 1 :(得分:0)
这是指令的v2。这是在angular中执行指令的正确方法吗?
app.directive('navigation', ['$parse', '$compile', function ($parse, $compile) {
return {
restrict: 'A',
templateUrl: 'views/widgets/navbar.html',
replace: true,
scope: {},
controller: ['$scope', '$state', function ($scope, $state) {
var menu = [];
var states = $state.get();
_.each(states, function(state, key) {
if(!_.isObject(state) || _.has(state, 'abstract') || _.has(state, 'parent')) {
return;
}
var object = {
text: _.has(state, 'data') && _.has(state.data, 'title')
? state.data.title : '(no title)',
state: state.name,
href: state.url
}
menu.push(object);
});
$scope.nav = {};
$scope.nav.menu = menu;
}],
link: function (scope, element, attrs) {
scope.nav.brand = attrs.navBrand;
console.log(scope);
}
};
}]);
模板:
<nav class="navbar navbar-default navbar-fixed-top">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">{{ nav.brand }}</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li ng-repeat="node in nav.menu" active-tab="{{node.href}}">
<a ui-sref="{{node.state}}"><b>{{node.text}}</b></a>
</li>
</ul>
</div>
指令致电:
<div navigation nav-brand="My Brand"></div>