当指令不是ui-view的一部分时,从控制器更新指令范围

时间:2015-05-08 20:57:37

标签: javascript angularjs angularjs-directive angularjs-scope angular-ui-router

我的问题非常具体,所以我无法在任何地方找到这个特定场景的答案,我确实设法获得了我需要的功能,但想知道是否有更好的方法。我将从解释问题开始。

在index.html中,我有以下内容:

<html>
 ...
 <lumx-navbar></lumx-navbar>
 <div class="wrap">
    <div ui-view></div>
 </div>
 ...
</html>

lumxnavbar是应用程序导航栏的指令

nav.js

 module.exports = function(appModule) {
    appModule.directive('lumxNavbar', function(UserFactory, $window, $rootScope) {
        return {
            template: require('./nav.html'),
            controller: function($scope) {
                $scope.nav = require('../../static-data/nav.json');
                $scope.user = $rootScope.user;
                $scope.logout = function() {
                    UserFactory.logout();
                    $scope.user = '';
                    $window.location.href = '/#/login';
                };

            }
        };
    });
};

nav.html

<header>
 ...
 <span ng-show="user" class="main-nav--version">Logged in as: {{user}}</span>
 ...
</header>

因此,应用程序以登录页面开始,此时任何地方都没有可用的用户变量。一旦用户登录,将有一个用户从服务返回。

我的路线看起来像这样(我使用的是angular-ui-router)

    $stateProvider
        .state('anon', {
            abstact: true,
            template: '<ui-view/>',
            data: {
                access: false
            }
        })
        .state('anon.login', {
            url: '/login',
            template: require('../views/login.html'),
            controller: 'LoginCtrl'
        });
    $stateProvider
        .state('user', {
            abstract: true,
            template: '<ui-view/>',
            data: {
                access: true
            }
        })
        .state('user.home', {
            url: '/home',
            template: require('../views/home.html'),
            controller: 'HomeCtrl'
        })
    ...

所以我的想法是,一旦用户登录导航栏就会改变

enter image description here

到此:

enter image description here

我发现可靠地实现这一目标的唯一方法是执行以下操作

在$ rootScope中实例化变量

appModule.run(function($rootScope, $location, UserFactory, $state) {
    $rootScope.user = UserFactory.getUser();
...

然后从登录控制器设置相同的变量

...
        $scope.login = function (username, password) {
            UserFactory.login(username, password).then(function success(response) {
                $rootScope.user = response.data.user.username;
                $state.go('user.home');
            }, handleError);
        };
...

所以这会因为指令$scope.user = $rootScope.user;中的这一行而更新导航栏,但我的问题是是否有更好的方法可以在不使用$rootScope的情况下执行此操作,或者这是否适用于它?

任何输入都会被赞赏...... :)

0 个答案:

没有答案