AngularJS :使用指令的最佳方式
AngularJS : Best way to use directive
解释:
我为我的 angular 应用程序创建了一个 header
directive
。通过使用此指令,我们根据某些条件使用属性的 templateUrl
属性 来加载 template
。
html :
<div header></div>
指令:
app.directive('header', ['LS', function(LS) {
'use strict';
var user = LS.getData() === 'true' ? true : false;
return {
restrict: 'A',
replace: true,
templateUrl: user ? 'withlogin-header.html' : 'withoutlogin-header.html',
controller: ['$scope', 'LS', function ($scope,LS) {
$scope.login = function() {
return LS.setData(true);
}
$scope.logout = function() {
return LS.setData(false);
}
}]
}
}]);
withlogin-header.html :
<div>
User is logged in !!!
<input type="button" ng-click="logout()" value="Logout"/>
</div>
withoutlogin-header.html :
<div>
Hey buddy, log in !!!
<input type="button" ng-click="login()" value="Login"/>
</div>
要求:
我们必须根据 user roles
显示 different headers
。即,如果用户未登录,则我们必须显示 header 和 login button
,如果用户已经登录登录然后我们必须显示不同的 header 和 logout button
。
我们面临的挑战:
header
指令无法正常工作。当我们从 withoutlogin-header.html
单击 login button
时,它不会根据指令的 templateUrl
属性 中定义的条件加载另一个模板 withlogin-header.html
。
到目前为止我试过了:
Plnkr : http://plnkr.co/edit/w7AyUjSNA1o5NJp6tD1p?p=preview
任何即时帮助都将不胜感激。谢谢
您可以将模板放入单个指令中:
html:
<div ng-if="!isLoggedIn">
Hey buddy, log in !!!
<input type="button" ng-click="login()" value="Login"/>
</div>
<div ng-if="isLoggedIn">
Hey buddy, log in !!!
<input type="button" ng-click="login()" value="Login"/>
</div>
指令:
app.directive('header', function() {
'use strict';
return {
restrict: 'A',
replace: true,
templateUrl: 'withlogin-header.html',
controller: ['$scope', 'LS', function ($scope,LS) {
$scope.isLoggedIn = false;
$scope.login = function() {
LS.setData(true);
$scope.isLoggedIn = LS.getData() === 'true';
}
$scope.logout = function() {
LS.setData(false);
$scope.isLoggedIn = LS.getData() === 'true';
}
}]
}
});
编辑: 或者如果您想坚持使用单独的模板文件,您可以使用 ng-include
正如@Stepan Kasyanenko 提到的那样。
我有一个类似的情况,我为匿名用户显示特定的 URL 列表,并在用户登录后显示一个不同的列表。我通过在用户登录时添加 $watch 来解决这个问题 属性 以及用户在登录时选择的语言(多个国家的编码)
$scope.$watch(function () {
return User.language;
}, function (newVal, oldVal) {
if (newVal === undefined) {
newVal = "english";
}
navBarCtrl.AnonymousUrls = [];
navBarCtrl.AuthenticatedUrls = [];
$http.get('http://localhost:#####/Urls/' + newVal)
.success(function (data) {
navBarCtrl.sortAllUrlLists(data, navBarCtrl.AnonymousUrls, navBarCtrl.AuthenticatedUrls);
});//end of http get
}, true);
$scope.$watch(function () {
return User.isAuthenticated;
}, function (newVal, oldVal) {
navBarCtrl.isUserAuthenticated = newVal;
}, true);
这两个属性是在用户使用以下方式登录时设置的
this.submit = function () {
var data = angular.toJson(submitForm.credentials);
$http.post("/submitLogin", data)
.success(function (data, status, headers, config) {
submitForm.user.isAuthenticated = true;
submitForm.user.username = data.username;
submitForm.user.location = data.location;
submitForm.user.dsn = data.dsn;
submitForm.user.language = data.language;
$location.path(User.intededPath);
})
.error(function (data, status, headers, config) {
submitForm.user.isAuthenticated = false;
alert("fail");
}); // end of $http.post
} // end of submit
最后在视图中,我根据用户是否登录显示了以下正确列表
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li ng-class="{'dropdown':urlList.length>1}" ng-show="!navBarCtrl.isUserAuthenticated" ng-repeat="urlList in navBarCtrl.AnonymousUrls">
<a href="" data-toggle="dropdown" class="dropdown-toggle" ng-if="urlList.length>1">{{urlList[0].Label}} </a>
<ul class="dropdown-menu" ng-if="urlList.length>1">
<li ng-repeat="url in urlList" ng-if="$index > 0">
<a href="{{url.Path}}">{{url.Label}}</a>
</li>
</ul>
<a href="{{urlList[0].Path}}" ng-if="urlList.length==1">{{urlList[0].Label}}</a>
</li>
<li ng-class="{'dropdown':urlList.length>1}" ng-show="navBarCtrl.isUserAuthenticated" ng-repeat="urlList in navBarCtrl.AuthenticatedUrls">
<a href="" data-toggle="dropdown" class="dropdown-toggle" ng-if="urlList.length>1">{{urlList[0].Label}} <b class="caret"></b></a>
<ul class="dropdown-menu" ng-if="urlList.length>1">
<li ng-repeat="url in urlList" ng-if="$index > 0">
<a href="{{url.Path}}">{{url.Label}}</a>
</li>
</ul>
<a href="{{urlList[0].Path}}" ng-if="urlList.length==1">{{urlList[0].Label}}</a>
</li>
</ul>
</div>
希望这可以让您了解如何让您的工作正常进行。
检查这个 plunker 我已经创建了一个很棒的 directive
用于从服务器获取 dynamic header
模板。
我也对您的代码做了一些小改动。
希望一定能帮到你...
解释:
我为我的 angular 应用程序创建了一个 header
directive
。通过使用此指令,我们根据某些条件使用属性的 templateUrl
属性 来加载 template
。
html :
<div header></div>
指令:
app.directive('header', ['LS', function(LS) {
'use strict';
var user = LS.getData() === 'true' ? true : false;
return {
restrict: 'A',
replace: true,
templateUrl: user ? 'withlogin-header.html' : 'withoutlogin-header.html',
controller: ['$scope', 'LS', function ($scope,LS) {
$scope.login = function() {
return LS.setData(true);
}
$scope.logout = function() {
return LS.setData(false);
}
}]
}
}]);
withlogin-header.html :
<div>
User is logged in !!!
<input type="button" ng-click="logout()" value="Logout"/>
</div>
withoutlogin-header.html :
<div>
Hey buddy, log in !!!
<input type="button" ng-click="login()" value="Login"/>
</div>
要求:
我们必须根据 user roles
显示 different headers
。即,如果用户未登录,则我们必须显示 header 和 login button
,如果用户已经登录登录然后我们必须显示不同的 header 和 logout button
。
我们面临的挑战:
header
指令无法正常工作。当我们从 withoutlogin-header.html
单击 login button
时,它不会根据指令的 templateUrl
属性 中定义的条件加载另一个模板 withlogin-header.html
。
到目前为止我试过了:
Plnkr : http://plnkr.co/edit/w7AyUjSNA1o5NJp6tD1p?p=preview
任何即时帮助都将不胜感激。谢谢
您可以将模板放入单个指令中:
html:
<div ng-if="!isLoggedIn">
Hey buddy, log in !!!
<input type="button" ng-click="login()" value="Login"/>
</div>
<div ng-if="isLoggedIn">
Hey buddy, log in !!!
<input type="button" ng-click="login()" value="Login"/>
</div>
指令:
app.directive('header', function() {
'use strict';
return {
restrict: 'A',
replace: true,
templateUrl: 'withlogin-header.html',
controller: ['$scope', 'LS', function ($scope,LS) {
$scope.isLoggedIn = false;
$scope.login = function() {
LS.setData(true);
$scope.isLoggedIn = LS.getData() === 'true';
}
$scope.logout = function() {
LS.setData(false);
$scope.isLoggedIn = LS.getData() === 'true';
}
}]
}
});
编辑: 或者如果您想坚持使用单独的模板文件,您可以使用 ng-include
正如@Stepan Kasyanenko 提到的那样。
我有一个类似的情况,我为匿名用户显示特定的 URL 列表,并在用户登录后显示一个不同的列表。我通过在用户登录时添加 $watch 来解决这个问题 属性 以及用户在登录时选择的语言(多个国家的编码)
$scope.$watch(function () {
return User.language;
}, function (newVal, oldVal) {
if (newVal === undefined) {
newVal = "english";
}
navBarCtrl.AnonymousUrls = [];
navBarCtrl.AuthenticatedUrls = [];
$http.get('http://localhost:#####/Urls/' + newVal)
.success(function (data) {
navBarCtrl.sortAllUrlLists(data, navBarCtrl.AnonymousUrls, navBarCtrl.AuthenticatedUrls);
});//end of http get
}, true);
$scope.$watch(function () {
return User.isAuthenticated;
}, function (newVal, oldVal) {
navBarCtrl.isUserAuthenticated = newVal;
}, true);
这两个属性是在用户使用以下方式登录时设置的
this.submit = function () {
var data = angular.toJson(submitForm.credentials);
$http.post("/submitLogin", data)
.success(function (data, status, headers, config) {
submitForm.user.isAuthenticated = true;
submitForm.user.username = data.username;
submitForm.user.location = data.location;
submitForm.user.dsn = data.dsn;
submitForm.user.language = data.language;
$location.path(User.intededPath);
})
.error(function (data, status, headers, config) {
submitForm.user.isAuthenticated = false;
alert("fail");
}); // end of $http.post
} // end of submit
最后在视图中,我根据用户是否登录显示了以下正确列表
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li ng-class="{'dropdown':urlList.length>1}" ng-show="!navBarCtrl.isUserAuthenticated" ng-repeat="urlList in navBarCtrl.AnonymousUrls">
<a href="" data-toggle="dropdown" class="dropdown-toggle" ng-if="urlList.length>1">{{urlList[0].Label}} </a>
<ul class="dropdown-menu" ng-if="urlList.length>1">
<li ng-repeat="url in urlList" ng-if="$index > 0">
<a href="{{url.Path}}">{{url.Label}}</a>
</li>
</ul>
<a href="{{urlList[0].Path}}" ng-if="urlList.length==1">{{urlList[0].Label}}</a>
</li>
<li ng-class="{'dropdown':urlList.length>1}" ng-show="navBarCtrl.isUserAuthenticated" ng-repeat="urlList in navBarCtrl.AuthenticatedUrls">
<a href="" data-toggle="dropdown" class="dropdown-toggle" ng-if="urlList.length>1">{{urlList[0].Label}} <b class="caret"></b></a>
<ul class="dropdown-menu" ng-if="urlList.length>1">
<li ng-repeat="url in urlList" ng-if="$index > 0">
<a href="{{url.Path}}">{{url.Label}}</a>
</li>
</ul>
<a href="{{urlList[0].Path}}" ng-if="urlList.length==1">{{urlList[0].Label}}</a>
</li>
</ul>
</div>
希望这可以让您了解如何让您的工作正常进行。
检查这个 plunker 我已经创建了一个很棒的 directive
用于从服务器获取 dynamic header
模板。
我也对您的代码做了一些小改动。 希望一定能帮到你...