web-dev-qa-db-ja.com

AngularJSコントローラーをリロードする

私は、angularjsの初心者です。

私の問題は、ログインとログアウトを処理するユーザーコントローラーがあることです。サイトのヘッダーメニューを読み込むための別のコントローラーもあります。

ユーザーがサイトにログインすると、isAuthenticated変数がtrueに設定されます。変数がtrueに設定されている場合、ヘッダーを変更する必要がありますが、ヘッダービューを変更するにはコントローラーをリロードする必要があると思います。

ここに私のHeaderControllerのコード:

myapp.controller('HeaderController', ['$scope', '$location', '$window', 'AuthenticationService',  
    function HeaderController($scope, $location, $window, AuthenticationService) {
        $scope.isAuthenticated = AuthenticationService.isAuthenticated;

        if (AuthenticationService.isAuthenticated) {
            $scope.user.vorname = $window.sessionStorage.user.vorname;
        }
    }
]);

HeaderDirectiveのコードは次のとおりです。

myapp.directive('appHeader', function() {
  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
      if (attrs.isauthenticated == 'false') {
        scope.headerUrl = 'views/header/index.html';
      } else {
        scope.headerUrl = 'views/header/isAuthenticated.html';
      }
    },
    template: '<div ng-include="headerUrl"></div>'
  }
});

私のindex.html:

<div ng-controller="HeaderController">
  <app-header isauthenticated="{{isAuthenticated}}"></app-header>
</div>

ユーザーがページにログインした場合、どのようにコントローラーをリロードできますか?

PS:私の悪い発音を許してください。

15
Rico Berger

コントローラをリロードする必要はありません。 Angularは、$scope.isAuthenticated状態が変更されたときにテンプレートを変更するのに十分スマートです。

あなたのコードにある問題の1つは、$scope.isAuthenticatedが定義されると、もう変更されないことです。ユーザーがログインするときにAuthenticationService.isAuthenticated = trueを設定しているが、JavaScriptのスカラー値は参照ではなく値によってコピーされるため、その変更は$scope.isAuthenticatedプロパティに反映されていません。

AuthenticationService.isAuthenticatedプロパティをブール値から関数に変更するなど、多くのアプローチがあります。

angular.module('auth', [])
.factory('AuthenticationService', function () {
    // private state
    var isAuthenticated = false;

    // getter and setter
    var auth = function (state) {
        if (typeof state !== 'undefined') { isAuthenticated = state; }
        return isAuthenticated;
    };

    // expose getter-setter
    return { isAuthenticated: auth };
});

次に、その関数を$ scopeに割り当てます。

$scope.isAuthenticated = AuthenticationService.isAuthenticated;

次に、テンプレートで関数を使用します(括弧を忘れないでください)

<app-header isauthenticated="{{ isAuthenticated() }}"></app-header>

編集:

実用的な例を示すためにプランクを書いている間、私はディレクティブのリンク関数が複数回呼び出されないことを認識しましたこのstackoverflowスレッドisauthenticated属性の変化を観察するためにディレクティブを修正しました:

angular.module('directives', [])
.directive('appHeader', function() {
  var bool = {
    'true': true,
    'false': false
  };

  return {
    restrict: 'E',
    link: function (scope, element, attrs) {
      attrs.$observe('isauthenticated', function (newValue, oldValue) {
        if (bool[newValue]) { scope.headerUrl = 'authenticated.html'; }
        else { scope.headerUrl = 'not-authenticated.html'; }
      });
    },
    template: '<div ng-include="headerUrl"></div>'
  }
});

そして これが実際の例です

13
Pau Fracés

ユーザーが認証された後、次のコードを追加します。

// To refresh the page
$timeout(function () {
    // 0 ms delay to reload the page.
    $route.reload();
}, 0);

$timeout$routeをコントローラーに含めることを忘れないでください。

myapp.controller('HeaderController', ['$scope', '$location', '$window', 'AuthenticationService', '$timeout', '$route',
function HeaderController($scope, $location, $window, AuthenticationService, $timeout, $route)
17
mpatel