在login_form.html中,当用户登录时,我在LoginCtrl中设置isLoggedIn = true.但是这会导致重新呈现下面的完整html,这会再次导致ng-init.
我该如何避免这种循环?
<div ng-controller="LoginCtrl" ng-init="isLoggedIn = false" class="span4 pull-right"> <div ng-switch on="isLoggedIn"> <div ng-switch-when="false" ng-include src="'login_form.html'"></div> <div ng-switch-when="true" ng-include src="'profile_links.html'"></div> </div> </div>
以下是登录表单的HTML –
<form class="form-inline"> <input type="text" placeholder="Email" ng-model="userEmail" class="input-small"/> <input type="password" placeholder="Password" ng-model="userPassword" class="input-small"/> <button type="submit" ng-click="login(userEmail,userPassword)" class="btn">Sign In</button> </form>
以下是控制器 –
angularApp.controller('LoginCtrl',function($scope,currentUser){ $scope.loginStatus = function(){ return currentUser.isLoggedIn(); }; /* $scope.$on('login',function(event,args) { $scope.userName = args.name; }); $scope.$on('logout',args) { $scope.isLoggedIn = false; });*/ $scope.login = function(email,password){ currentUser.login(email,password); }; $scope.logout = function(){ currentUser.logout(); }; });
吹是服务 –
angularApp.factory('currentUser',function($rootScope) { // Service logic // ... // var allUsers = {"rob@gmail.com": {name: "Robert Patterson",role: "Admin",email: "rob@gmail.com",password: "rob"},"steve@gmail.com":{name: "Steve Sheldon",role: "User",email: "steve@gmail.com",password: "steve"}} var isUserLoggedIn = false; // Public API here return { login: function(email,password){ var user = allUsers[email]; var storedPass = user.password; if(storedPass === password){ isUserLoggedIn = true; return true; } else { return false; } },logout: function(){ $rootScope.$broadcast('logout'); isUserLoggedIn = false; },isLoggedIn: function(){ return isUserLoggedIn; } }; });
我猜测在login_form.html中,您会执行以下操作:
<a ng-click="isLoggedIn=true">login</a>
在将isLoggedIn设置为true之前,这是您的范围的样子:
在isLoggedIn设置为true之后,这就是您的范围:
希望这些图片清楚地说明了为什么这会导致你的问题.
有关原型继承以原始方式工作的原因的更多信息,请参阅What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
如上所述,您有三种解决方案:
>在模型的父级中定义一个对象,然后在子级中引用该对象的属性:parentObj.isLoggedIn
>在login_form.html中使用$parent.isLoggedIn – 这将引用$parent范围中的原语,而不是创建一个新原语.例如.,
< a ng-click =“$parent.isLoggedIn = true”> login< / a>
>在父作用域上定义一个函数,并从子作用中调用它 – 例如,setIsLoggedIn().这将确保设置父范围属性,而不是子范围属性.
更新:在查看HTML时,您实际上可能有两个级别的子范围,因为ng-switch和ng-include都创建了自己的范围.因此,图片需要孙子范围,但三个解决方案是相同的…除了#2,你需要使用$parent.$parent.isLoggedIn – 丑陋.所以我建议选项1或3.
Update2:@ murtaza52在问题中添加了一些代码…从控制器中删除ng-init =“isLoggedIn = false”(您的服务通过其isUserLoggedIn变量管理登录状态)并在控制器中启用loginStatus():< ; div ng-switch on =“loginStatus()”>.