AngularJS 模块/范围共享
Posted
技术标签:
【中文标题】AngularJS 模块/范围共享【英文标题】:AngularJS Modules/Scope Sharing 【发布时间】:2014-01-12 02:56:25 【问题描述】:我最近开始使用 AngularJS,我现在构建应用程序的方式是这样的:
MainController.js
var app = angular.module('app', ['SomeController', 'MainController']);
app.controller('MainController', function ($scope)
// do some stuff
SomeController.js
var SomeController= angular.module('SomeController', []);
SomeController.controller('SomeController', function ($scope)
$scope.variable = "test";
// do some otherstuff
我遇到的问题是范围没有在模块之间共享。例如,从 MainController 我无法获取变量“test”。
对此的最佳做法是什么?我是否将所有控制器存储在 1 个文件中的 1 个模块中? 我怎样才能拥有 2 个控制器的 1 页并在它们之间共享$scope
,或者将所有内容都放在一个控制器中是否可以?
【问题讨论】:
这绝对是 X/Y 问题。如果你需要做这样的事情,那你就做错了。更新您的答案以解释您实际想要完成的工作。 基本上我在问我应该怎么做,我不一定需要这样做。 看我的回答,只要确保你将属于一起的东西打包在一起,而不是耦合不应该耦合的东西。 【参考方案1】:您可以使用这样的服务:Live demo here (click).
JavaScript:
var otherApp = angular.module('otherApp', []);
otherApp.factory('myService', function()
var myService =
someData: ''
;
return myService;
);
otherApp.controller('otherCtrl', function($scope, myService)
$scope.shared = myService;
);
var app = angular.module('myApp', ['otherApp']);
app.controller('myCtrl', function($scope, myService)
$scope.shared = myService;
);
标记:
<div ng-controller="otherCtrl">
<input ng-model="shared.someData" placeholder="Type here..">
</div>
<div ng-controller="myCtrl">
shared.someData
</div>
Here's a nice article on sharing data with services.
您还可以嵌套控制器以使父控制器的范围属性由子范围继承: http://jsbin.com/AgAYIVE/3/edit
<div ng-controller="ctrl1">
<span>ctrl1:</span>
<input ng-model="foo" placeholder="Type here..">
<div ng-controller="ctrl2">
<span>ctrl2:</span>
foo
</div>
</div>
但是,子级不会更新父级 - 只有父级的属性会更新子级。
您将使用“点规则”让子级的更新影响父级。这意味着将您的属性嵌套在一个对象中。由于父母和孩子都有相同的对象,因此该对象的更改将反映在两个地方。这就是对象引用的工作方式。很多人认为最好的做法是不使用继承,而是将所有内容放在具有隔离范围的指令中。
【讨论】:
感谢您的解释,我应该说在一页/或部分页面上有多个模块是一种常见的做法吗?我知道我做错了。 @Chancho 您没有使用多个模块(也不应该使用)。您正在使用一个依赖于另一个模块的模块。这种耦合很好,但似乎你的想法不正确。假设Module A
是您创建的一种工具集。也许它有一个服务、目录和一个控制器,它们一起工作以提供一个很好的功能。现在,您正在创建一个应用程序,因此您创建了Module B
。您决定 Module B
可以使用您在 Module A
中创建和打包的功能,因此 Module B
将依赖于 Module A
。
好吧,我想我现在明白了,但是驻留在模块中的控制器呢?基本上我现在正在做的是在里面创建一个带有控制器的模块。然后在另一个控制器中,我将该模块添加为该模块的依赖项。我认为这是我走错路的地方。 - 所以改写我的问题:我如何将多个控制器与其范围链接在一起?
@Chancho 很可能,您确实需要服务解决方案,就像我说的那样。那是将这些范围链接在一起,因为它们都引用同一个对象。否则,他们的范围继承,但它是有限的。 jsbin.com/AgAYIVE/3/edit
@Chancho 是的。请牢记大局——控制器并不意味着关心如何处理数据。控制器只是数据进出视图的枢纽。考虑到这一点 - 控制器在这里的工作只是将视图中的数据与服务中的数据相关联。然后依赖于该服务的其他东西可以用它做一些事情。如果您理解了这个概念,您应该会发现使用该数据的任何东西都存在问题,具体取决于控制器。【参考方案2】:
您可以使用$rootScope
,每个 Angular 应用程序都只有一个根范围。
Reference
app.controller('MainController', function ($scope, $rootScope)
$rootScope.data = 'App scope data';
【讨论】:
每个模块都有自己的 $rootScope。 即使您可以访问这样的全局并共享状态——这被称为“公共耦合”,它是 5 分中的 4 级(内容耦合是最高的) )。 #badPractice、#tightCoupling、#theBadTypeOfComplexity 。 Mmmm...我正在运行 Angular 1.5.5,每个模块当然没有得到它自己的 $rootScope。 肯定有一个$rootScope,或者肯定应该存在,除非你做错了什么,比如在模块之间传递它或者将它分配给某个地方的另一个变量。我在 OP 的问题中没有看到任何表明该变量可能不是 static 变量的内容(这完全适用于 $rootScope,并避免了服务的复杂性)。跨度>以上是关于AngularJS 模块/范围共享的主要内容,如果未能解决你的问题,请参考以下文章