我刚刚开始学习MEAN堆栈,并尝试从头开始构建一个身份验证页面(尽管我知道我可以使用开箱即用的身份验证,但我这样做是为了有一个背景知识)但我发现它有点在我的导航栏上更新文本很棘手。
我的index.html
看起来像这样;
<nav class="navbar navbar-default navbar-fixed-top" ng-controller="HeadController">
<div class = "container-fluid">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">{{user.name}}</a></li>
</ul>
</div>
</nav>
<div class="container" ng-view></div>
我的app.js
看起来像这样;
var app = angular.module('app',['ngRoute'])
.service("userService", function () {
this.user = {};
this.getUser = function () {
return this.user;
};
this.setUser = function (user) {
this.user = user;
};
})
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/login', {
templateUrl: 'partials/login.html',
controller: 'LoginCtrl as login'
})
.when('/user/profile',{
templateUrl: 'partials/profile.html',
controller: 'ProfileCtrl as profile'
})
.otherwise({
redirectTo: '/login'
});
}]);
app.controller("HeadController", [
'$scope',
'userService',
function ($scope, userService) {
$scope.user = userService.getUser();
}]);
app.controller("LoginCtrl", [
"$location",
"userFactory",
"userService",
function ($location, userFactory, userService) {
var login = this;
login.user = {
username: '',
password: '',
isRemember: true
};
login.login = function () {
userFactory.login(login.user)
.success(function (user) {
userService.setUser(user);
$location.path("/user/profile");
})
.error(function (err) {
console.log(err);
});
};
}]);
最后,我的userFactory.js
看起来像这样;
function login(user) {
return $http({
url: '/api/login/',
method: "POST",
data: user,
headers: {
'Content-Type': 'application/json'
}
});
}
return{login:login};
每当我登录时,我都希望{{user.name}}
更新,但这不会发生。我不知道怎么做到这一点。我该怎么做才能实现这一目标?
答案 0 :(得分:2)
问题在于userService.setUser(user)
将服务器在内存中的引用替换为&#34; user&#34;上一个用户对象(以及内存中的引用)绑定到HeadController
的$ scope之后的对象。解决这个问题的方法很简单:
1。使用setUser
突变(而不是替换)原始对象:
this.setUser = function(newUserData) {
angular.extend(this.user, newUserData);
};
2。动态引用&#34; name&#34;在你的模板中
<li><a href="#">{{ userService.getUser().name }}</a></li>
3。(首选IMO,虽然绝对不是最容易实现的)在您的用户服务中制作自定义事件处理程序,以便在您调用setUser
时,回调&#34;听众&#34;将被调用。这样您就可以在HeadController
:
userService.onUserUpdate(function(newUser) {
$scope.user = newUser; // or userService.getUser();
});
并保持模板/视图更清晰,更具声明性,就像你现在拥有它一样:
<li><a href="#">{{ user.name }}</a></li>
这可以像这样实现。在userService
添加:
var privateUserUpdateListeners = [];
this.onUserUpdate = function(cb)
if (angular.isFunction(cb)) {
privateUserUpdateListeners.push(cb);
// Return a callback that can be used to deregister the listener.
// In production code, you may want to wrap this function
// to ensure that it may only get called once.
return function() {
var index = privateUserUpdateListeners.indexOf(cb);
privateUserUpdateListeners.splice(index, 1);
};
}
};
this.broadcastUserUpdate = function(user) {
privateUserUpdateListeners.forEach(function(cb) {
cb(user);
});
};
然后在setUser
中,您可以添加如下广播:
this.setUser = function(user) {
this.user = user;
this.broadcastUserUpdate(user);
};
这应该可以解决问题。