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 模板。

我也对您的代码做了一些小改动。 希望一定能帮到你...

http://plnkr.co/edit/GWIozm?p=preview