如何在 AngularJS 中的 Controller 之间正确共享和更新数据?
How to properly share and update data between Controllers in AngularJS?
所以我正在尝试使用 AngularJS 编码,而不是使用 $scope 或 $rootScope,而是命名控制器。
http://codepen.io/anon/pen/LpxOwx
这是 Angular 部分:
.controller('demoController', function(Fac){
var vm = this;
vm.theme = Fac.theme;
vm.changeTheme = function(theme) {
Fac.changeTheme(theme);
vm.theme = Fac.theme;
};
})
.controller('secondController', function(Fac){
var vm = this;
vm.changeTheme = function(theme) {
Fac.changeTheme(theme);
};
})
.factory('Fac', function() {
var fac = {
theme: '',
changeTheme: function(theme) {
fac.theme = theme === 'indigo' ? 'lime' : 'indigo';
}
}
return fac;
});
我分叉了一个代码笔来说明我的问题。 demoController 按预期工作并更新视图。但是在 secondController 中使用相同的 Factory 时它不会 "work"。我认为它可以工作,但不会在 demoController 中更新。
我理解 Angular 数据绑定的方式是,我需要做的就是使用工厂在绑定到它们的控制器之间共享数据,并根据变化进行相应更新。
我敢肯定,我在这里犯的是一个非常愚蠢的错误。我做错了什么?
更新:
感谢您的回答!不过,我遇到了一个新的(相关的?)问题:
http://plnkr.co/edit/cRa2FTkpbIsJ9TLzu5bD?p=preview
你能告诉我如何在 LoginCtrl 和 ToolbarCtrl 之间绑定用户,以便 ng-show 和 ng-hide 可以在登录和注销时更新吗?当我登录时,工具栏不会相应更新。我必须刷新整个页面而不是使登录可见。当我注销时它起作用了,因为我在 ToobarCtrl 中明确设置了 vm.user= {};
。
这是一个working version of your codepen
我只是使用了一个子变量来绑定到视图中。将原始变量从工厂绑定到控制器通常会导致这个麻烦之王。
工厂是这样的:
.factory('Fac', function() {
var fac = {
theme: {value:'indigo'},
changeTheme: function(theme) {
console.log(theme);
fac.theme.value = theme === 'indigo' ? 'lime' : 'indigo';
}
}
两个控制器看起来像这样:
.controller('secondController', function(Fac){
var vm = this;
vm.theme = Fac.theme;
vm.changeTheme = Fac.changeTheme;
})
我在视图中这样使用它:
<md-button href="#" class="md-primary md-raised" ng-click=vm.changeTheme(vm.theme.value)>
Change theme
</md-button>
希望对您有所帮助,
编辑: 在这里我解释了为什么这实际上不适用于原始变量
一种简单的方法是将工厂对象一直传递到视图:
.controller('demoController', function(Fac){
var vm = this;
vm.Fac= Fac;
});
然后在视图中使用对象的属性:
<md-button href="#" class="md-primary md-raised" ng-click=vm.Fac.changeTheme(vm.Fac.theme)>
Change theme
</md-button>
Current theme is {{vm.Fac.theme}}
现在您没有将原语传递给子作用域并且控制器更精简了。
请注意,这不适用于工厂回调中可能需要某些控制器逻辑的所有情况,但在许多情况下,它可以避免重复创建可能并不真正需要的控制器属性。
您还可以对工厂对象进行分区,以尽量减少在可行的范围内重复相同的属性
所以我正在尝试使用 AngularJS 编码,而不是使用 $scope 或 $rootScope,而是命名控制器。
http://codepen.io/anon/pen/LpxOwx
这是 Angular 部分:
.controller('demoController', function(Fac){
var vm = this;
vm.theme = Fac.theme;
vm.changeTheme = function(theme) {
Fac.changeTheme(theme);
vm.theme = Fac.theme;
};
})
.controller('secondController', function(Fac){
var vm = this;
vm.changeTheme = function(theme) {
Fac.changeTheme(theme);
};
})
.factory('Fac', function() {
var fac = {
theme: '',
changeTheme: function(theme) {
fac.theme = theme === 'indigo' ? 'lime' : 'indigo';
}
}
return fac;
});
我分叉了一个代码笔来说明我的问题。 demoController 按预期工作并更新视图。但是在 secondController 中使用相同的 Factory 时它不会 "work"。我认为它可以工作,但不会在 demoController 中更新。
我理解 Angular 数据绑定的方式是,我需要做的就是使用工厂在绑定到它们的控制器之间共享数据,并根据变化进行相应更新。
我敢肯定,我在这里犯的是一个非常愚蠢的错误。我做错了什么?
更新:
感谢您的回答!不过,我遇到了一个新的(相关的?)问题:
http://plnkr.co/edit/cRa2FTkpbIsJ9TLzu5bD?p=preview
你能告诉我如何在 LoginCtrl 和 ToolbarCtrl 之间绑定用户,以便 ng-show 和 ng-hide 可以在登录和注销时更新吗?当我登录时,工具栏不会相应更新。我必须刷新整个页面而不是使登录可见。当我注销时它起作用了,因为我在 ToobarCtrl 中明确设置了 vm.user= {};
。
这是一个working version of your codepen
我只是使用了一个子变量来绑定到视图中。将原始变量从工厂绑定到控制器通常会导致这个麻烦之王。
工厂是这样的:
.factory('Fac', function() {
var fac = {
theme: {value:'indigo'},
changeTheme: function(theme) {
console.log(theme);
fac.theme.value = theme === 'indigo' ? 'lime' : 'indigo';
}
}
两个控制器看起来像这样:
.controller('secondController', function(Fac){
var vm = this;
vm.theme = Fac.theme;
vm.changeTheme = Fac.changeTheme;
})
我在视图中这样使用它:
<md-button href="#" class="md-primary md-raised" ng-click=vm.changeTheme(vm.theme.value)>
Change theme
</md-button>
希望对您有所帮助,
编辑:
一种简单的方法是将工厂对象一直传递到视图:
.controller('demoController', function(Fac){
var vm = this;
vm.Fac= Fac;
});
然后在视图中使用对象的属性:
<md-button href="#" class="md-primary md-raised" ng-click=vm.Fac.changeTheme(vm.Fac.theme)>
Change theme
</md-button>
Current theme is {{vm.Fac.theme}}
现在您没有将原语传递给子作用域并且控制器更精简了。
请注意,这不适用于工厂回调中可能需要某些控制器逻辑的所有情况,但在许多情况下,它可以避免重复创建可能并不真正需要的控制器属性。
您还可以对工厂对象进行分区,以尽量减少在可行的范围内重复相同的属性