在我们的总体布局中,我们有一个侧边栏,其中包含一些用户详细信息,如名称和缩略图。还有一些不同的东西。
我们有想法加载带有指令的侧栏,其中有2个模板,1个登录时和1个登出时。
显示并不显示用户详细信息。
但是,我们有一个名为sidebar的指令,使用2中的任何一个
App.directive('sidebar',['UserService','$ compile',function(User,$ compile){
var getTemplate = function() {
console.warn(User.isLogged);
var templateUrl = "#sidebar" + ((User.isLogged) ? '_loggedin' : '') + "_template";
console.log('requesting template: [%s]', templateUrl);
return $(templateUrl).html();
};
return {
restrict: 'A',
link: function link(scope, element, attrs) {
var tmpl = getTemplate();
element.html(tmpl);
element.replaceWith($compile(element.html())(scope));
},
template: getTemplate()
};
}]);
我们在服务中加载用户详细信息
App.factory('UserService', [function userService() {
var User = {
isLogged: false,
username: ''
};
return User;
}]);
登录表单接受此UserService
作为依赖项,并将其isLogged
设置为true
但是当isLogged
发生变化时,如何让指令重新标注侧边栏?
我们这样做是正确的吗?
答案 0 :(得分:1)
有一个阶段称为编译阶段,其中有角度
遍历DOM以识别所有已注册的指令 模板。对于每个指令,它然后根据指令转换DOM 规则(模板,替换,转换等),并调用compilefunction 如果它存在结果是编译的模板函数,它将调用链接 从所有指令中收集的函数。
基本上,你不能有条件地加载模板 - 它会编译你给它的第一个模板。如果要动态渲染视图,可以在模板中使用两个带有ng-show指令的div:
<div ng-show="user.isLogged">// logged in content</div>
<div ng-show="!user.isLogged">// logged out content</div>
你可能认为你需要在你的指令中注入一个工厂 - 我刚试过这个并且它不起作用!我相信这是因为指令只能与作用域链上的指令建立单向和双向绑定。考虑到这一点,我将用户对象带入了应用程序范围:
App.controller("AppCtrl", function($rootScope, UserService) {
$rootScope.user = UserService;
})
然后使用指令中的开放范围:
app.directive("sidebar", function() {
return {
restrict: "A",
template: '<div>' +
'<div ng-show="user.isLogged">Logged In</div>' +
'<div ng-show="!user.isLogged">Logged Out</div></div>',
}
})
此处的用户对象是通过范围链接找到的。因为该指令没有隔离范围(我没有声明范围属性),所以它通过范围链找到它 - 直到根范围。从某种意义上说,这当然是一种“全球性”,很容易被隐藏起来:
$scope.user = somethingElse
不是最漂亮的解决方案,但它可以胜任。
您还可以在链接函数中有条件地操作DOM,或者更好的是 - 将这种逻辑加载到使用嵌套模板并解析的路由器上。