gpt4 book ai didi

angularjs - ng-include 导致 Controller block 重新渲染

转载 作者:行者123 更新时间:2023-12-04 13:00:43 25 4
gpt4 key购买 nike

我正在尝试将 ng-switch 与下面的 ng-include 一起使用。问题在于 ng-init 和整个 Controller block 在任何 ng-includes 更改时重新渲染。

在 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>

下面是 Controller -
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', function(event, 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;
}
};
});

最佳答案

我相信您的问题是原型(prototype)继承工作方式的结果。 ng-include 创建自己的子范围。在子作用域中分配原始值会在该作用域上创建一个新属性,该属性会隐藏/隐藏父属性。

我猜在 login_form.html 中,当用户登录时,您会执行以下操作:

<a ng-click="isLoggedIn=true">login</a>

在 isLoggedIn 设置为 true 之前,您的作用域如下所示:

before assignment

isLoggedIn 设置为 true 后,您的作用域如下所示:

after assignment

希望这些图片清楚地说明了为什么这会导致您出现问题。

有关原型(prototype)继承为何以这种方式与原语一起工作的更多信息,请参阅 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。

    更新2 :@murtaza52 为问题添加了一些代码...删除 ng-init="isLoggedIn = false"从您的 Controller (您的服务通过其 isUserLoggedIn 变量管理登录状态)并在您的 Controller 中打开 loginStatus(): <div ng-switch on="loginStatus()"> .

    这是 working fiddle .

    关于angularjs - ng-include 导致 Controller block 重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14101099/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com