假设我有一个非常简单的服务,上面有一些属性。如果我在控制器中使用该服务,将服务的属性放在作用域上,以便它们绑定到我的视图,并从控制器更新它们,它们将在视图中更新。这是我期望的行为。但是,如果从控制器范围之外的指令修改了相同服务的属性,则视图不会更新(除非某些事件触发了在控制器范围内更新的监视?)。显然我在这里缺少一些基本的东西,但搜索搜索搜索并没有让我得到答案。
以下是JSFiddle的示例。
app = angular.module('app', []);
// simple service to track application's logon status
app.factory('AuthService', function () {
var status = {
isLoggedIn: false
};
return {
status: status,
login: function () {
status.isLoggedIn = true;
console.log('user logged in');
},
loggedIn: function () {
return status.isLoggedIn;
},
logout: function () {
status.isLoggedIn = false;
console.log('user logged out');
}
}
});
app.controller('AuthViewCtrl', function ($scope, AuthService) {
// bind some service attributes, functions to the scope so that we can use them in our view
$scope.loggedIn = AuthService.loggedIn;
$scope.login = AuthService.login;
$scope.logout = AuthService.logout;
$scope.stat = AuthService.status;
});
// a simple directive to allow elements to log out of the app on click
app.directive('appLogout', function (AuthService) {
return function (scope, element) {
element.bind('click', function () {
AuthService.logout();
});
}
});
// a simple directive to allow elements to log into the app on click
app.directive('appLogin', function (AuthService) {
return function (scope, element) {
element.bind('click', function () {
AuthService.login();
});
}
});
随附的html:
<div ng-app="app">
<div ng-controller="AuthViewCtrl">
<strong>Are we logged in?</strong>
<ul>
<li>service func on scope: <strong>{{ loggedIn() }}</strong></li>
<li>service prop on scope: <strong>{{ stat.isLoggedIn }}</strong></li>
</ul>
<button ng-click="login()">log in from controller scope</button>
<button ng-click="logout()">log out from controller scope</button>
<button ng-click="loggedIn()">call AuthService.loggedIn()</button>
</div>
<button app-login>log in from directive</button>
<button app-logout>log out from directive</button>
</div>
启动时会退出该应用。如果您“从控制器登录[/ out]”,它调用发布到作用域的服务功能,则会在视图中立即更新监视的服务值。但是,如果您点击“从指令登录[/ out]”,则不会更新监视的服务值(如果您只是从作用域内调用AuthService.loggedIn(),它们将更新)。
所以,我想我的问题是,处理这个问题的最佳方法是什么?我在哪里观看服务价值时误入歧途?
谢谢, 亚当
答案 0 :(得分:1)
问题是你在“角度”之外“服务”你的服务:
element.bind('click', function () {
AuthService.login();
});
因此,您需要将呼叫包裹在$apply
:
element.bind('click', function () {
scope.$apply(function() {
AuthService.login();
});
});