在AngularJS中实现对象工厂的最佳方法

时间:2014-01-17 19:18:09

标签: angularjs coffeescript

我在AngularJS中搜索对象的最佳方法。目标是像model = new Model 'wowwowwow'

一样使用它

所以我开始采用这种方法:

app.factory 'Model', ->
  (blah) ->
    Model =
      blah: ''
      foo: []
    Model.blah = blah
    Model

然后我想在不能从类实例访问的单独函数中移动构造函数:

app.factory 'Model', ->
  constructor = (blah) ->
    @blah = blah
    @

  (blah) ->
    constructor.call
      blah: ''
      foo: []

最后我想使用coffeescript的目标并试图以一种明显的方式解决我的任务:

app.factory 'Model', ->
  class Model
    blah: ''
    foo: []
    constructor: (blah) ->
      @blah = blah
  (blah) ->
    new Model blah

但是在最后一种情况下根本不起作用:

var1 = new Model 'test'
var1.foo.push 'blah'
var2 = new Model 'asdasd'
console.log var2.foo

这里的问题是创建后的var2将具有与var1相同的值(它们实际上是链接的)。

Here是解决此问题的方法。

所以问题是

  1. 我的第三种方法出了什么问题?

  2. 如何更改第3种方法以使其与coffeescript的OOP功能一起使用。

  3. 我的任务有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

google plus angular community post开始讨论之后,Dean Sofer就角度分类和子类化做了很好的解释:https://gist.github.com/ProLoser/5645860

对于您的问题,Model应定义为:

app.factory 'Model', ->
  class Model
    constructor: (blah) ->
      @blah = blah
      @foo   = []
  (blah) ->
    new Model blah

回答评论#4:

@SET这是因为您将数组分配给原型,有点类似于在Java类上使用静态字段。

每次推送/弹出该数组时,您都在使用共享原型数组实例。

当您对字符串执行相同操作时,您不会操纵共享实例,因为javascript字符串是不可变的。你正在做的是为你的对象实例分配新的字符串(而不是原型)。

Heres真的发生在幕后:

您的声明

foo: []
blah: ''

转换为:

Model.prototype.blah = '';
Model.prototype.foo = [];

当您操纵这些成员时,您生成的代码(或多或少):

a.blah = 'aaa'; // New string on the a object, not on the Model prototype
b.blah = 'bbb'; // New string on the b object, not on the Model prototype

a.foo.push('aaa'); // Push to the foo shared array
b.foo.push('bbb'); // Push to the foo shared array

你也可以通过以下方式获得你想要做的事情:

a.foo = ['aaa']; // a.foo is a new independent array
b.foo = ['bbb']; // b.foo is a new independent array

但是这些foo只是隐藏原型,但仍然存在。

无论如何,也许你应该寻找有关javascript原型继承的更多信息。