2016-03-21 12 views
1

私がいることを見出しディレクティブ構築しようとしている:ログインしている場合、ログアウトした場合は、ユーザ名とログアウトボタン AngularJSでディレクティブをリロードする方法は?

  • を表示する必要があり、上述したもの
  • を非表示にする

    私はこの情報をキャプチャし、イベント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>としてこれを使用しています。

    +1

    ヘッダーディレクティブは制限されてはなりませんあなたが要素として使っているので、 '' restrict:restrict''の代わりに '' restrict: '' E''を使うことはできますか? – Minato

    +3

    あなたは実際に私が言うことから指示を全く使用していません.HTML5には 'header'要素があり、あなたの要素を何か別のものにするのは混乱しない方がよいでしょう。属性の場合は問題ありませんが、別の名前を付ける必要があります。 – Makoto

    +0

    私は使用例を '

    'として追加しましたが、明確にするために名前を変更し、これを要素として使用することは良い考えです。 –

    答えて

    1

    これが動作することはできませんディレクティブといくつかの基本的な問題があるように見えます:

    は、

    1)属性ディレクティブとして宣言しました。 ヘッダ属性ディレクティブrestrict: "A",を作成しましたが、それを要素ディレクティブ<header ng-controller...</header>として使用しています。制限するプロパティはrestrict: "E"である必要があります。あるいは、他の人がコメントしたように指示を使用していない。

    2)Transcludeはあなたがfalseにtranscludeを設定しているが、あなたはtranscludeが真でなければなりませんので、内容のディレクティブを使用しようとしている falseです。

    あなたの問題を解決するには、これを解決策としてお勧めします。 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; 
           }); 
          } 
         }; 
        }); 
    
    +0

    ありがとう@Dr Jones!私の問題を解決すると説明しているように、 'restrict" E "'と 'transclude:true'を使用します。 *また、*、私は古典的なJavaScriptミスをしていました - クローズ内で "this"を使用していました...代わりに 'var self = this;'を使用してその問題を解決しました。追加するもう一つのことは、 '$ on 'で放送を聴くことは指令とコントローラの両方で働いているので、私はコントローラでのみこれを行うことにしました。 –

    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?? 
           }); 
          } 
         }; 
        }); 
    
    0

    あなたの解決策は、イベントの放送の使用量が常にエラーになりやすいし、テストおよびデバッグすることは一般に困難である、素晴らしいではありません。あなたがする必要があるのは、現在のプロファイルオブジェクトを格納しているサービスを作成し、ヘッダーディレクティブ(および現在のユーザーを使用/変更できる他のサービス)にそのサービスへの参照を格納することです。

    サービス

    '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); 
     
    
     
    })();

    あなたのヘッダーディレクティブ

    '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' 
     
        }));

    +0

    あなたのIIFEが文脈の中で ''厳密な ';を使用して移動するか、または厳密なモードと互換性のないライブラリを破壊する可能性のあるグローバルな空間に吊り上げられます。 – Makoto

    +0

    @Makotoポイントは?それは議論の話題とは関係ないものの、賢明に使うべきです – Yerken

    関連する問題