Angular Basic Factory绑定不更新控制器

时间:2015-04-22 05:21:24

标签: angularjs angular-services

我正在尝试创建一个SPA网站,其中我有多个依赖于AuthService的控制器,该服务只负责告诉所有控制器用户是否已登录并且用户是谁。 AFAIK因为所有控制器共享相同的服务对象,所以更改应该传播给它们,但到目前为止还没有发生这种情况。

我的代码如下:

我有一个NavbarController和一个LoginController。 NavbarController负责根据AuthService的Logged属性显示Login / Logout链接。 LoginController负责登录面板并通过AuthService调用服务器上的登录。

  

AuthService

(function () {
    var auth = angular.module('Auth', []);
    auth.factory('AuthService', ['$http', function ($http) {
        var obj = {};
        obj.User = {};
        obj.Logged = true;

        obj.GetUser = function () {
            $http.get('api/Account/UserDetails')
            .success(function (data) {
                obj.User = data;
                obj.Logged = true;
            })
        }

        obj.Login = function (data) {
            var func = $http.post('api/Account/Login', data);
            func.success(function (data) {
                if (data.StatusCode == 200) {
                    obj.GetUser();
                }
            });
            return func;
        }

        obj.Logoff = function () {
            $http.get('api/Account/Logoff')
                .success(function () {
                    obj.User = {};
                    obj.Logged = false;
                });
        }
        return obj;
    }]);
})();
  

的LoginController

(function () {
    var login = angular.module('Login', ['LoginService','Auth']);

    login.controller('LoginController', ['accountService','AuthService', function (accountService,authService) {
        this.OnFocus = function(obj)
        {
            $(obj.target).closest(".textbox-wrap").addClass("focused");
        }

        this.OnBlur = function(obj)
        {
            $(obj.target).closest(".textbox-wrap").removeClass("focused");
        }

        this.loginCredentials = {};

        this.Login = function () {
            authService.Login(this.loginCredentials)
                .success(function (data) {
                    alert(data.StatusCode);
                })
                .error(function () {
                    alert("error");
                });
        }

    }]);

    login.directive('hcCheckbox', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attr) {
                element.iCheck({
                    checkboxClass: 'icheckbox_square-blue',
                    increaseArea: '20%' // optional
                });
            }
        }
    });
})();
  

NavbarController

(function () {
    var app = angular.module('main');
    app.controller('NavbarController', ['AuthService', function (AuthService) {
        var self = this;
        self.Logged = AuthService.Logged;
        self.User = AuthService.User;
        self.Logoff = function()
        {
            AuthService.Logoff();
        }

    }]);
})();
  

Navbar html模板

<nav class="navbar navbar-default" ng-controller="NavbarController as NavbarCtrl">
    <div class="container">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="navegacion">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">HACSYS</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="navegacion">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">Home</a></li>
                <li><a href="#">Details</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li ng-hide="NavbarCtrl.Logged">
                    <a href="#/Login"> Login</a>
                </li>
                <li ng-show="NavbarCtrl.Logged">
                    <a ng-click="NavbarCtrl.Logoff()" href=""> Logoff</a>
                </li>
            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>

我知道我可以使用$ watch将更改传播到其他控制器,但这种方式对我来说似乎更清晰,我已经看到了其他有用的示例,我仍然无法弄清楚我的代码出了什么问题

1 个答案:

答案 0 :(得分:2)

为了确保在所有嵌套作用域中正确传播更改,您需要通过引用绑定到对象。如果绑定到基元,它会在范围上创建值的副本,从而有效地破坏范围变量之间的链接。要解决此问题,请通过引用绑定:

app.controller('NavbarController', ['AuthService', '$scope', function (AuthService, $scope) {
    var self = this;        
    $scope.AuthService = AuthService;
    self.Logoff = function()
    {
        $scope.AuthService.Logoff();
    }
}]);

当您通过引用进行绑定时,您注入AuthService的任何控制器都将按预期绑定和传播。

app.controller('otherController', function($scope, AuthService) {
      $scope.AuthService = AuthService;
});

HTML

<div ng-controller="otherController">
   <div ng-show="AuthService.Logged">
       User is logged in!
   </div>
</div>