tur*_*ner 5 javascript twitter-bootstrap angularjs angularjs-directive
我有一个带有navbar指令和基本注册/登录功能的应用程序.我想在用户登录后更改导航栏上的一些单词(从"注册/登录"到"退出"),但我无法找到最佳(甚至是一种)方式来执行此操作.我已经尝试将我想要更改的变量/绑定的值设置为在用户登录时更新的工厂,但这不起作用,并且指令不会使用其新值更新.
我的代码附在下面,特定的解决方案是值得赞赏的,但并不是真的有必要,如果有人能指出我正确的方向,如何做到这将是非常有帮助的.
我试过的解决方案:
不幸的是,这些都不会导致指令变量动态更新.我觉得解决方案很简单,但我想不出我应该做什么.
潜在解决方案
navbar.html
<nav class="navbar navbar-static-top navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#/">
<span class="glyphicon glyphicon-star"></span> Home
</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-6">
<ul class="nav navbar-nav">
<li><a ui-sref="message">Message</a></li>
<li><a ui-sref="list">User List</a></li>
<li><a ui-sref="schedule">Schedule</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a ng-href="{{ vm.accountStatusLink }}">{{ vm.accountStatus }}</a></li>
</ul>
</div>
</div>
</nav>
Run Code Online (Sandbox Code Playgroud)
navbar.directive.js
(function() {
'use strict';
angular
.module('app')
.directive('mainNavbar', mainNavbar);
mainNavbar.$inject = ['userFactory'];
function mainNavbar(userFactory) {
var directive = {
restrict: 'E',
templateUrl: 'app/components/navbar/navbar.html',
scope: {
creationDate: '='
},
controller: NavbarController,
controllerAs: 'vm',
bindToController: true
};
return directive;
function NavbarController() {
var vm = this;
// solution 1 (doesn't work)
vm.accountStatus = userFactory.userStatus;
vm.accountStatusLink = userFactory.userStatusLink;
// solution 2 (doesn't work)
//vm.accountStatus = userFactory.getUserStatus();
//vm.accountStatusLink = userFactory.getUserStatusLink();
}
}
})();
Run Code Online (Sandbox Code Playgroud)
user.factory.js
(function() {
'use strict'
angular
.module('app')
.factory('userFactory', userFactory);
userFactory.$inject = ['$http', '$cookies'];
function userFactory($http, $cookies) {
var userStatusLink = '#/user/';
var userStatus = 'Sign Up / Log In';
var service = {
verifyUser: verifyUser,
storeUser: storeUser,
userStatusLink: userStatusLink,
userStatus: userStatus
};
return service;
/* verifyUser() snip */
function storeUser(user) {
$cookies.putObject('user', user); // stores user obj in cookies
userStatusLink = '#/signout/';
userStatus = 'Sign Out';
}
/* solution 2 getters
function getUserStatus() {
return userStatus;
}
function getUserStatusLink() {
return userStatusLink;
}
*/
}
})();
Run Code Online (Sandbox Code Playgroud)
更新:
userFactory.storeUser(user)在.success回调中异步发生:
$http.post('someurl').success(function(user) {
userFactory.storeUser(user);
});
Run Code Online (Sandbox Code Playgroud)
您是否尝试过创建 getUserStatusLink 和 getUserStatus 方法,并将您的视图绑定到这些方法?
function userFactory($http, $cookies) {
...
var service = {
...
getUserStatusLink: function() {
return userStatusLink;
},
getUserStatus: function() {
return userStatus;
}
};
...
}
Run Code Online (Sandbox Code Playgroud)
然后在您的导航栏控制器中:
function NavbarController() {
...
vm.accountStatusLink = userFactory.getUserStatusLink();
vm.accountStatus = userFactory.getUserStatus();
}
Run Code Online (Sandbox Code Playgroud)
当 userFactory 中更新 userStatusLink 和 userStatus 时,这应该执行您希望执行的操作。
更新:
由于您的storeUser()方法是异步调用的,因此当您设置新值时,它不会触发另一个摘要周期。因此,您应该强制 Angular 使用 $timeout 服务执行摘要循环:
userFactory.$inject = [ ..., '$timeout'];
function userFactory( ..., $timeout) {
...
function storeUser(user) {
...
// forces Angular to perform a digest cycle, thus refreshing your view
$timeout(function() {
userStatusLink = '#/signout/';
userStatus = 'Sign Out';
});
}
...
}
Run Code Online (Sandbox Code Playgroud)
更新2:
使用 jsFiddle 来实现此实现。我提供了两种方法,以便您可以看到使用 $timeout 和不使用 $timeout 的区别:http://jsfiddle.net/HB7LU/15366/
我在一个地方引导您错误,更新您的控制器变量以直接访问该方法,如下所示:
function NavbarController() {
...
// remove the parens at the end of userFactory.getUserStatusLink();
vm.accountStatusLink = userFactory.getUserStatusLink;
// remove the parens at the end of userFactory.getUserStatus();
vm.accountStatus = userFactory.getUserStatus;
}
Run Code Online (Sandbox Code Playgroud)
然后更新您的视图以实际调用方法:
<!-- add parens to view to make it actually call the methods -->
<li><a ng-href="{{ vm.accountStatusLink() }}">{{ vm.accountStatus() }}</a></li>
Run Code Online (Sandbox Code Playgroud)
最终更新:
事实证明 $timeout 是不必要的,因为 Angular 在 $http 服务的成功回调中执行摘要循环。只需更新视图以直接访问该方法就足以修复它。
| 归档时间: |
|
| 查看次数: |
169 次 |
| 最近记录: |