如何在AngularJS中重新加载指令?

时间:2016-03-21 04:44:28

标签: angularjs angularjs-directive

我正在尝试构建一个头指令:

  • 如果已登录,则应显示用户名和注销按钮
  • 如果退出,应隐藏上述内容

我正在使用捕获此信息的自定义登录服务,并广播事件loginlogout。我在标题的控制器和指令中成功地监听了这些事件。

如何在这些事件上重新加载指令?

loginService.js:

angular.module("app")
    .service("loginService", ["$http", "$rootScope", function ($http, $rootScope) {
        var loggedIn = false,
            _username = "";

        this.logIn = function (username, password) {
            // do some validation...

            loggedIn = ...validation was successful;
            _username = username;

            if (loggedIn) {
                $rootScope.$broadcast("login");
            }
        };
        this.getUsername = function () {
            return _username;
        };
        this.isLoggedIn = function () {
            return loggedIn;
        };
        this.logOut = function () {
            loggedIn = false;
            $rootScope.$broadcast("logout");
        };
    }]);

headerController.js

angular.module("app")
    .controller("headerController", ["loginService", "$rootScope", "$location", function (loginService, $rootScope, $location) {
        this.isLoggedIn = loginService.isLoggedIn();
        this.username = "";

        $rootScope.$on("login", function (event) {
            this.isLoggedIn = loginService.isLoggedIn();
            this.username = loginService.getUsername();
        });

        this.logOut = function () {
            loginService.logOut();
            this.isLoggedIn = loginService.isLoggedIn();
            this.username = "";
            $location.path("/login"); // redirecting
        };
    }]);

header.html中:

<header ng-controller="headerController as header">
    <span ng-if="header.isLoggedIn">{{header.username}} <button ng-click="header.logOut()">Log Out</button></span>
</header>

headerDirective.js

angular.module("app")
    .directive("header", function () {
        return {
            restrict: "A",
            transclude: false,
            templateUrl: "app/header/header.html",
            controller: "headerController",
            link: function (scope, element, attrs) {
                scope.$on("login", function (event) {
                    // show the ng-if in header.html??
                });
                scope.$on("logout", function (event) {
                    // hide the ng-if in header.html??
                });
            }
        };
    });

我将其用作<div header></div>

3 个答案:

答案 0 :(得分:1)

看起来该指令存在一些基本问题,不允许这样做:

1)声明为属性指令: 您已创建标头属性指令:restrict: "A",但您将其用作元素指令:<header ng-controller...</header>。限制属性应为restrict: "E"。或者您没有像其他人评论的那样使用该指令。

2)Transclude为false 您已将transclude设置为false,但您尝试将该指令与内容一起使用,因此transclude应为true。

要解决您的问题,我建议将其作为解决方案: 1.在其父容器视图中声明您的头部指令就是这样。

<ian-header></ian-header>

ianHeader.html

<header>
    <span ng-if="header.isLoggedIn">{{header.username}} <button ng-click="header.logOut()">Log Out</button></span>
</header>

ianHeader.js

angular.module("app")
    .directive("ianHeader", function () {
        return {
            restrict: "E",
            templateUrl: "app/header/ianHeader.html",
            link: function (scope, element, attrs) {
                scope.header = {isLoggedIn: false};
                scope.$on("login", function (event) {
                    // show the ng-if in header.html??
                    scope.header.isLoggedIn = true;
                });
                scope.$on("logout", function (event) {
                    // hide the ng-if in header.html??
                    scope.header.isLoggedIn = false;
                });
            }
        };
    });

答案 1 :(得分:0)

如果您提供JS代码段会更容易,但无论如何一种方法可能是:

angular.module("app")
    .directive("header", function () {
        return {
            restrict: "A",
            transclude: false,
            templateUrl: "app/header/header.html",
            controller: "headerController",
            link: function (scope, element, attrs) {
                scope.$on("login", function (event) 
                {
                  //header should be the controllerAs you declared
                  //If you would provide JS snippet would be easier to debbug
                  scope.$parent.header.isLoggedIn= true;
                    // show the ng-if in header.html??
                });
                scope.$on("logout", function (event) 
                {
                   scope.$parent.header.isLoggedIn = false;
                    // hide the ng-if in header.html??
                });
            }
        };
    });

答案 2 :(得分:0)

您的解决方案并不是很好,事件广播的使用总是容易出错并且通常难以测试和调试。您需要做的是创建一个服务,该服务存储当前的配置文件对象并在header指令(以及可能使用/修改当前用户的其他服务)中存储对它的引用。

服务

&#13;
&#13;
'use strict';

(function() {

    function AuthService() {
      
        var Auth = {
           User: User //call some API for user authentication if using sessions
        };

        return Auth;
    }

    angular.module('app')
        .factory('Auth', AuthService);

})();
&#13;
&#13;
&#13;

您的标头指示

&#13;
&#13;
'use strict';

//do not use "header" as the name of directive 
angular.module('app')
  .directive('navbar', () => ({
    templateUrl: 'components/navbar.html',
    restrict: 'E',
    controller: function(Auth){
      this.user = Auth.User; 
    },
    controllerAs: 'navbar'
  }));
&#13;
&#13;
&#13;