Angular 基本工厂绑定不更新控制器
Angular Basic Factory Binding not updating Controllers
我正在尝试创建一个 SPA 网站,其中我有多个依赖于 AuthService 的控制器,该服务仅负责告诉所有控制器用户是否已登录以及用户是谁。据我所知,因为所有控制器都共享同一个服务对象,所以更改应该传播到它们,但到目前为止还没有发生。
我的代码如下:
我有一个 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 template
<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 将更改传播到其他控制器,但这种方式对我来说似乎更清晰,我已经看到其他有效的示例,但我仍然无法弄清楚我的代码出了什么问题
为了确保更改在所有嵌套范围内正确传播,您需要通过引用绑定到对象。如果你绑定到一个原语,它会在作用域上创建一个值的副本,有效地打破作用域变量之间的链接。要解决此问题,请按引用绑定:
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>
我正在尝试创建一个 SPA 网站,其中我有多个依赖于 AuthService 的控制器,该服务仅负责告诉所有控制器用户是否已登录以及用户是谁。据我所知,因为所有控制器都共享同一个服务对象,所以更改应该传播到它们,但到目前为止还没有发生。
我的代码如下:
我有一个 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 template
<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 将更改传播到其他控制器,但这种方式对我来说似乎更清晰,我已经看到其他有效的示例,但我仍然无法弄清楚我的代码出了什么问题
为了确保更改在所有嵌套范围内正确传播,您需要通过引用绑定到对象。如果你绑定到一个原语,它会在作用域上创建一个值的副本,有效地打破作用域变量之间的链接。要解决此问题,请按引用绑定:
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>