【发布时间】:2016-10-07 04:16:48
【问题描述】:
我无意中用我认为我只分配给范围的属性污染了服务。示例:
var ServiceFunction = function ServiceFunction(){
this.greeting = 'Hello';
};
var TestController = function TestController(testService){
var testCtrl = this;
testCtrl.testService = testService;
//here I make changes within the controller. This amends the service itself
testCtrl.testService.newProperty = 'new value';
};
angular.module('test',[])
.service('testService',ServiceFunction)
.controller(['testService',TestController])
这是一个 Plunker 来演示这种行为:
https://plnkr.co/edit/nDkNfKmQRtcBuJ0NUcHo?p=preview
我知道在将对象传递给函数时,JavaScript 按引用传递。除非这些对象被深度克隆。
我曾假设服务之外的某些东西可以访问该服务公开的对象等,但只能通过值访问,并且对该服务的任何更改都必须由该服务提供的 api 完成。似乎唯一的方法是使用 angular.copy 例如在上面的例子中testCtrl.testService = angular.copy(testService);
我猜这一定是预期的行为。如果是这样,除了性能优势之外,我认为这是一个缺点。
为什么 AngularJS 允许这种行为而不是“黑盒”提供者?
【问题讨论】:
-
这就是 JavaScript 原型继承的工作原理;函数是对象。顺便说一句,提供者是单例的,使用
angular.copy“克隆”提供者可能会产生意想不到的副作用。 -
防止用户误解 JS 的工作原理不是框架的责任。顺便说一句,你期待什么样的答案?
-
@estus 我只是认为,如果您要将某物称为服务,它应该表现得像服务。如果我为您提供将一箱牛奶送到您家的服务,而您拿走那箱牛奶并取出几瓶,我不希望从我的货车的每个板条箱中取出 2 瓶牛奶,或者您可以改变一切在我的面包车里装一箱酸奶。我期望的答案可能会突出我自己看不到的好处。
-
@Claies 是的,你说得对,提供者是单身人士,
angular.copy会导致意想不到的副作用。我原以为必须使用手动观察器来跟踪模型更改。 -
您的 cmets 是合适的,但放错了位置。 Angular 无法将 JavaScript 更改为类型安全的语言,如果没有对它的语言支持,试图使提供程序成为类型安全的,这将比它所提供的好处付出更多的努力,并使结果更麻烦,更不可用。
标签: angularjs angularjs-service angularjs-factory angularjs-provider