在Angular ui-router中如何从一个视图向另一个视图发出事件?

时间:2016-05-13 16:20:57

标签: javascript angularjs angular-ui-router

用例是将登录按钮更改为文本"以xxx"登录认证后。

我已将页面分为3个视图:标题,内容,页脚登录按钮位于标题视图中。当我点击登录时,它会转换为" app.login " state,内容视图更改为允许用户输入用户名和密码。

这是路由代码:

app.config(['$stateProvider', '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider) {
    $stateProvider
    .state('app', {
        url: '/',
        views: {
            'header': {
                templateUrl: 'static/templates/header.html',
                controller: 'AppController'
            },
            'content': {
                templateUrl: 'static/templates/home.html',
                controller: 'HomeController'
            },
            'footer': {
                templateUrl: 'static/templates/footer.html',
            }
        }
    })
    .state('app.login', {
        url: 'login',
        views: {
            'content@': {
                templateUrl : 'static/templates/login.html',
                controller  : 'LoginController'
           }
        }
    })

html模板的代码如下:

<li><span ng-if='loggedIn' class="navbar-text">
    Signed in as {{currentUser.username}}</span>
</li>
验证成功后,

LoginController $scope.loggedIn标志设置为true,但如何将该标志填充到标题视图?

据我了解,我不能在html模板中使用$scope.loggedIn,因为$ scope在两个控制器中是不同的。我知道如果LoginController是AppController的子代,那么我可以在LoginController中用一个事件调用$scope.$emit并在AppController中调用$scope.$on来捕获它。但在这种情况下,两个控制器是针对不同的视图,我怎样才能使它们成为父子?

我知道我可以使用$ rootScope但是因为我告诉污染$ rootScope是最后的选择,所以我试图找到最佳实践。这必须是一个非常常见的用例,所以我必须遗漏一些明显的用法。

3 个答案:

答案 0 :(得分:1)

您可以使用工厂来处理身份验证:

app.factory( 'AuthService', function() {
  var currentUser;

  return {
    login: function() {
      // logic 
    },
    logout: function() {
      // logic 
    },
    isLoggedIn: function() {
      // logic 
    },
    currentUser: function() { 
      return currentUser; 
    }
  };
});

可以在AuthService中注入controllers。 以下代码监视服务中值的更改(通过调用指定的函数),然后同步更改的值:

app.controller( 'AppController', function( $scope, AuthService ) {
  $scope.$watch( AuthService.isLoggedIn, function ( isLoggedIn ) {
    $scope.isLoggedIn = isLoggedIn;
    $scope.currentUser = AuthService.currentUser();
  });
});

答案 1 :(得分:0)

您是否使用任何服务来保存已记录的用户数据?基本上,服务是单身,所以它们有助于解决这类问题而不会污染$ rootScope。

app.controller('LoginController', ['authService', '$scope', function (authService, $scope) {
  $scope.login = function(username, password) {
    //Some validation
    authService.login(username, password);
  }
}]);

app.controller('HeaderController', ['authService', '$scope', function (authService, $scope) {
    $scope.authService = authService;
}]);

在标题html文件中:

<span ng-if="authService.isAuthenticated()">
    {{ authService.getCurrentUser().userName }}
</span>

答案 2 :(得分:0)

在这种情况下,我通常选择使用服务来协调事物。服务使用new进行实例化,然后进行缓存,这样您就可以有效地获得单例。然后你可以放入一个简单的子/ pub模式,你就可以了。基本骨架如下

angular.module('some-module').service('myCoordinationService', function() {
    var callbacks = [];
    this.register = function(cb) {
      callbacks.push(cb);
    };

    this.send(message) {
      callbacks.forEach(function(cb) {
        cb(message);
      });
    };
}).controller('controller1', ['myCoordinationService', function(myCoordinationService) {
  myCoordinationService.register(function(message) {
     console.log('I was called with ' + message);
  });
}).controller('controller2', ['myCoordinationService', function(myCoordinationService) {
  myCoordinationService.send(123);
});