【问题标题】:AngularJS - Polluting provider, services, and factories externallyAngularJS - 从外部污染提供者、服务和工厂
【发布时间】: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


【解决方案1】:

从问题下的 cmets 中的讨论得出结论,AngularJS 似乎没有具体的理由允许这种行为,只是服务没有被封装,只有一个 api 来访问它们。

因此,JavaScript 的常规规则适用,即传递给函数的服务,例如directivecontroller 通过引用传递给服务对象,并且对该引用的任何更改都会直接在源处更新对象。由于服务是单例的,因此更改会反映在使用该服务的整个应用程序中。

这种方法有性能优势,因为它是 JavaScript 的自然行为。

【讨论】:

    猜你喜欢
    • 2015-07-22
    • 2015-07-24
    • 2016-02-18
    • 2013-10-15
    • 2015-07-01
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多