我有一个UserService
angular.module('mango.services', [])
.factory('UserService', function() {
var user = {
id: null,
name: 'anonymous.'
};
function getUser(){
return user;
}
function setUser(val){
user = val;
}
return {
getUser: getUser,
setUser: setUser,
}
});
一个NavbarController
.controller('NavbarController', ['$scope','$location','UserService', function($scope, $location, UserService){
$scope.isActive = function (viewLocation) {
return viewLocation === $location.path();
};
$scope.username = UserService.getUser().name;
}])
和一个UserController,我有registerUser和loginUser函数。
.controller('UserController', ['$scope', '$http', 'UserService', function($scope, $http, UserService) {
$scope.loginUser = function(){
$http.post('/api/1.0/user/authenticate', $scope.user)
.success(function(data,status,headers,config){
if (data["valid"] === true) {
UserService.setUser(data.user);
} else {
$scope.flashes = data.flashes;
$scope.user.password = "";
}
})
}
和HTML
<li ng-switch="username">
<a ng-class="{ active: isActive('/user/login')}" href="#/user/login" ng-switch-when="anonymous."><i class="fa fa-sign-in"></i> Sign in</a>
<a ng-class="{ active: isActive('/user/logout')}" href="#/user/logout" ng-switch-default><i class="fa fa-sign-out"></i> Sign out</a>
</li>
正如您所看到的,如果data.valid为true,我正在尝试设置UserService的用户。
服务器正在返回一个有效的json对象。
但NavbarController中的用户名值仍为“匿名”。
我在JS方面不是很有经验,但我读过有关广播和观看的内容。我相信这可能是正确的方法。但也许有一个更好的。
我相信为什么它不起作用是因为工厂返回一个单身人士。但是,使用工厂毫无意义。
基本上我想要的是,如果凭证有效,则设置user.name user.id client-app-wide。稍后它应该通过“检查客户端用户是否有效”服务。我的会话cookie已加密。但这超出了问题的范围。
我现在需要的是从UserController设置应用程序或者更确切地说是NavbarController的用户数据。我该怎么做,所以它也更新DOM aka ng-switch获得不同的值。
答案 0 :(得分:2)
它无法正常工作,因为您没有创建某种类型的绑定:使用$scope.username = UserService.getUser().name
,您可以在该时刻获得用户名(即anonymous
)并永久保留它。其中一个方法是使用手表。在NavbarController中,将以前的代码替换为:
$scope.$watch(
function() {
return UserService.getUser().name;
},
function(newval) {
$scope.username = newval;
}
);
这会在每个摘要周期中通过函数调用生成应用程序。这个函数调用并不慢,所以没关系。
如果您不想要这种开销,您也可以使用事件来完成。在NavbarController中:
$scope.username = UserService.getUser().name;
$scope.on("loggedIn", function(event, newUserName) {
$scope.username = newUserName;
});
在UserController中(将$rootScope
添加到依赖项):
if (data["valid"] === true) {
UserService.setUser(data.user);
$rootScope.$broadcast("loggedIn", data.user);
}
答案 1 :(得分:1)
您确实需要$watch
来username
和NavbarController
而不是UserService
同步$scope.username = UserService.getUser().name;
,而$scope.username
只设置$scope.$watch(
function () { return UserService.getUser().name; },
function (newVal) {
$scope.username = newVal;
}
);
的初始值初始化Controller时{1}}:
User
工厂确实设计为整个应用程序的单例,这是您应该保存应用程序的状态的地方(即您的模型,如NavbarControll
模型)。控制器是短暂的,每次创建模板时都会重新创建。
但是,如果你有一个长寿命的控制器(就像你的sync
),那么在服务器和控制器之间维护$watch
的责任在于使用models
的程序员。
在某些情况下,当需要控制器间通信(不一定涉及{{1}})时,广播消息很有用。
答案 2 :(得分:0)
我编写了一个简短的函数,可以将数据放入Object而无需替换它。 您可以在服务中使用它。这样你就不需要使用手表了。您可以使用Angular的正常摘要循环。 例如,看到这个简单的控制器&amp;服务:
演示:JSFidde - http://jsfiddle.net/y09kx7f7/1/ 断言测试
<强>控制器:强>
#SACRED-HEART-COLLEGE {
font-family:"Trajan Pro Regular";
font-size: 24px;
color: rgb(30, 30, 117);
position: absolute;
top: 0;
}
每次更改用户名时,控制器将自动进行无人值守!
<强>服务强>
app.controller('dem',function($scope,me){
$scope.user=me.user; // {name:'user name'}
})
我写的cloneInto函数:
.factory('me',function($timeout){
var obj={}
obj.user={name:'hello'}
$timeout(function(){ //Example of change the data
newUser={name:'israel'}
cloneInto(obj.user,newUser)
},1000)
return obj
})