Authentication 更新$scope并在视图中反映
在我的angularjs应用程序中,我为每个页面呈现“导航栏”div 在用户登录并重定向到详细信息页面后,我希望我正在更新未反映到视图中的$scope 为了反映$scope的更改,我使用$scope.$apply()调用$digest。似乎它没有更新,$scope更新仍然没有反映在我的观点中 我的代码如下所示:Authentication 更新$scope并在视图中反映,authentication,angularjs,view,angularjs-scope,Authentication,Angularjs,View,Angularjs Scope,在我的angularjs应用程序中,我为每个页面呈现“导航栏”div 在用户登录并重定向到详细信息页面后,我希望我正在更新未反映到视图中的$scope 为了反映$scope的更改,我使用$scope.$apply()调用$digest。似乎它没有更新,$scope更新仍然没有反映在我的观点中 我的代码如下所示: CONTROLLER: function NavCtrl($scope){ //as isAuth false $scope.showLogin = true;
CONTROLLER:
function NavCtrl($scope){
//as isAuth false
$scope.showLogin = true;
$scope.showLogout = false;
}
function ProductDetails($scope){
//as isAuth true
$scope.showLogin = false;
$scope.showLogout = true;
if (!$scope.$$phase) {
//$digest or $apply to reflect update of scope update
$scope.$apply();
}
}
VIEW:
<div id="navigation-bar" ng-controller="NavCtrl">
<li ng-show="showLogin"><a href="/login">Login</a></li>
<li ng-show="showLogout"><a href="/logout">Logout</a></li>
</div>
控制器:
函数NavCtrl($scope){
//因为我是假的
$scope.showLogin=true;
$scope.showLogout=false;
}
函数ProductDetails($scope){
//正如我所说的那样
$scope.showLogin=false;
$scope.showLogout=true;
如果(!$scope.$$phase){
//$digest或$apply用于反映范围更新的更新
$scope.$apply();
}
}
视图:
我做错了什么?我遗漏了什么吗?顺便说一句,我还问了其他问题,比如,但这对我的情况没有帮助。问题是,你应该使用一个控制器来实现这一点。以下是一个控制器示例,该控制器将根据其
连接的
范围变量显示正确的菜单。该值由AJAX或代码中的其他地方设置
控制器:
function NavCtrl($scope, $rootScope){
$scope.showLogin = true;
$scope.showLogout = false;
$rootScope.$watch("connected", function() {
if ($rootScope.connected) {
$scope.showLogin = false;
$scope.showLogin = true;
} else {
$scope.showLogin = true;
$scope.showLogin = false;
}
});
}
视图:
主要问题是您使用的是两个不同的控制器。每个控制器都有自己的作用域(即作用域不是全局的),因此当您在ProductDetails中更改showLogin时,更改的只是本地作用域,而不是NavCtrl的作用域
您可以重写它以使用一个控制器,也可以在控制器之间传递数据,有几种方法可以做到这一点:
- 您可以在$rootScope上设置数据。rootScope是一个全局作用域,所有控制器都可以访问它,并且您可以始终在模板中使用它。我建议将rootScope保持在最小值,因为rootScope在任何地方都是共享的,并且最终可能会有一大堆变量
- 您可以通过服务传递数据。每个服务只创建一个实例,因此不同的控制器可以访问相同的服务并获取相同的数据
- 您可以使用.$broadcast向任何子控制器发送信号。这可能也是最好保持在最低限度,很多广播迟早会让你慢下来(尽管限制应该很高)
.factory('AuthUserService', ['$http','$q',
function($http, $q) {
var user = {};
return {
user: function() {
return user;
},
login: function(user_credentials) {
$http.post('/login', user_credentials).then(
function(response) {
angular.copy(response.data, user);
...
});
},
logout: function() { ...
}
}
}])
我正在设置$scope.connected=true;在我的“ProductDetails”控制器中?可以吗?在我看来,它仍然没有反映出来。不,因为它不在同一范围内。您可以在NavCtrl中使用$rootScope.connected并在任何控制器中更改该值。这样,您将使用根作用域。我改变了我的答案来告诉你怎么做。
.factory('AuthUserService', ['$http','$q',
function($http, $q) {
var user = {};
return {
user: function() {
return user;
},
login: function(user_credentials) {
$http.post('/login', user_credentials).then(
function(response) {
angular.copy(response.data, user);
...
});
},
logout: function() { ...
}
}
}])
.controller('NavCtrl', ['AuthUserService','$scope',
function(AuthUserService, $scope) {
$scope.user = AuthUserService.user();
$scope.$watch('user.name', function(name) {
if(name) {
$scope.loggedIn = true;
} else {
$scope.loggedIn = false;
}
});
}])
<div ng-controller="NavCtrl">
<li ng-hide="loggedIn"><a href="/login">Login</a></li>
<li ng-show="loggedIn"><a href="/logout">Logout</a></li>
</div>