关于控制器之间的共享状态。我很难找到正确的方法来从SO推荐的所有可能解决方案中做到这一点。我用这个草图来说明我到目前为止使用工厂的基本想法。
工厂myFactory
包含共享变量sharedVar
。
控制器Ctrl1, Ctrl2, Ctrl3
想要始终访问更新的版本。他们也可以拨打updateViaHttp
。
这是工厂的正确目的吗? (一般来说,分享国家, 特定于服务和提供商等其他选项
如果是这样,如何以正确的方式观察sharedVar
的更改? (通过
对象的引用,$ watch,events(broadcast,on),...)
答案 0 :(得分:1)
你可能正在寻找类似pubsub服务的东西:
https://www.npmjs.com/package/angular-pubsub
但是,根据我的经验,通过适当的设计,您可以最大限度地减少在非嵌套控制器之间共享数据的必要性。
有时,对于登录凭据,权限以及全部应用程序包含的内容等内容,这是不可避免的。在这种情况下,您可以使用服务确实在控制器之间共享/获取状态,或者您可以使用完全成熟的pubsub机制。
工厂只是指定服务的另一种方式。调用时,工厂会提供服务实例。这项服务可用于您想要的一切,其中一项是在您的控制器之间共享状态。
您可以通过多种方式观看共享变量,最简单的是继承范围,但正如您所提到的,有时您的控制器不一定会继承其范围。然后,您可以使用pubsub服务或仅在两个控制器的共享作用域上广播事件(例如$ rootScope,它是应用程序的所有控制器范围的父级)。
如果您要使用现有的pubsubservice,那么您的实现控制器仍然需要实际进行订阅并观察特定变量并相应地更新其相应的范围。但是,如果您以一种控制器从共享范围继承变量的方式设计应用程序,则可以避免这种情况。然后他们将使用正常的角度机制自动更新他们的东西。遗憾的是,这并不总能实现,然后您需要实现pubsub服务。
答案 1 :(得分:1)
你已经掌握了基本的想法,假设是工厂'你的意思是' service' - 我知道,这有点令人困惑,因为服务是使用工厂功能声明的。也就是说,这是一个重要的区别,以便您更容易找到文档等。
只需使用对象引用并注意watch depths in Angular(我的首选方法)或明确注册$ watch语句(仍然要注意观察深度)来观察更改。一般来说,我认为你不应该过度使用广播,因为它可能会使你的代码变得有点混乱。在这种情况下,它也会破坏服务点,这是共享状态的来源。
我创建服务的一般模式是将我想要使用的所有东西绑定到一个对象(包括数据和函数),然后在工厂函数中返回该对象。有时您必须引入一些额外的嵌套,以便Javascript原型继承不会让您感到困扰(再次参见手表深度)但这是一般的想法。
您的设置的示例服务:
toString()
答案 2 :(得分:1)
工厂与服务与提供商 - 仅差异与Dependency Injector如何为您提供实例有关。服务专门用于提供单例,但只是工厂的包装器,可添加单例特定功能。没有什么可以阻止你从工厂返回单身人士。
使用服务来共享状态 - 您需要单例和服务才能轻松定义和注入单例。
SomeService:
var foo = {
bar = 'a';
};
function getFoo() {
return foo;
}
SomeController[SomeService injected here] :
$scope.foo = SomeService.getFoo();
$scope.$watch('foo.bar', ...);
$scope.setFooBar = function(val) {
$scope.foo.bar = val;
};
<a href="" ng-click="setFooBar('2')">2</a>
这里的一般模式是永远不要做
$scope.foo = { bar: 'Some other reference' };
因为当你覆盖它时,依赖于SomeService的所有其他东西都将不获得新的引用 - &#34;臭名昭着的&#34; always use a "dot" in $scope stuff issue