【问题标题】:Why dont Backbone models work correctly when using CoffeeScript class inheritance为什么使用 CoffeeScript 类继承时 Backbone 模型不能正常工作
【发布时间】:2015-02-08 05:56:32
【问题描述】:

我看过几篇关于如何将 CoffeeScript 的扩展功能与 Backbone 一起使用的帖子,但我无法让它工作。以下代码:

Backbone = require 'Backbone'

# The backbone way
Base = Backbone.Model.extend (
    initialize: ->
)

Model  = Base.extend (

    initialize: ->
        console.log 'initialize called'
        @on 'change:foo', ->
            console.log 'foo changed (Base)'

    defaults: (
        foo: 'bar'
    )
)

model = new Model()
model.set 'foo', 'baz'
console.log model.get 'foo'



# The coffeescript way with double ineritance
class Base2 extends Backbone.Model
    constructor: ->

class Model2 extends Base2

    constructor: ->
        console.log 'constructor called (Base2)'
        @on 'change:foo', ->
            console.log 'foo changed (Base2)'

    defaults: (
        foo: 'bar'
    )

model2 = new Model2 (foo: 'bar')

model2.set 'foo', 'baz2'
console.log model2.get 'foo'

投掷:

  % coffee index.coffee                                                                                                                                                                            
initialize called
foo changed (Base)
baz
constructor called (Base2)
TypeError: Cannot read property 'foo' of undefined
  at Model2._.extend.set 

你也可以在这里玩http://codepen.io/guyht/pen/LEOdZr?editors=001

【问题讨论】:

    标签: javascript backbone.js coffeescript


    【解决方案1】:

    您的问题是您通过指定自己的constructor 来替换Backbone 的构造函数。 Backbone 需要使用自己的构造函数来设置所有 Backbone 内部结构,你的类构造函数代码应该在 initialize 中,就像你使用 Backbone 的 extend 函数而不是 CoffeeScript 的 extends 关键字时一样:

    class Base2 extends Backbone.Model
        initialize: ->
    
    class Model2 extends Base2
    
        initialize: ->
            console.log 'initialize called (Base2)'
            @on 'change:foo', ->
                console.log 'foo changed (Base2)'
    
        defaults: (
            foo: 'bar'
        )
    

    更新的演示:http://codepen.io/anon/pen/myqxWY

    【讨论】:

    • 一直在玩这个,当我使用初始化(而不是构造函数)时它确实有效,但我仍然觉得很奇怪我必须实现一个初始化函数才能让模型工作。在我看来,使用默认的 _.extends 会更可靠。
    • @mrwooster 您不必实现初始化函数,您只需覆盖构造函数。 codepen.io/anon/pen/OPOEQa 在没有定义初始化的情况下工作正常。我怀疑如果你用 _.extend 覆盖构造函数,你会看到同样的问题
    • @mrwooster 不编写自己的构造函数在框架中很常见,经常发生。
    • @ivarni - 是的,我明白了,但我的问题更多是关于 为什么 构造函数看起来是两个独立的函数时会干扰初始化函数.. ..
    • @mrwooster 它们是两个独立的函数。初始化是为了让你挂钩和设置东西,构造函数是为了让框架设置自己的东西。当您覆盖构造函数时,您必须调用原始构造函数或对其进行反向工程。正如您所发现的那样,覆盖它并将其留空会破坏事物。这就是您覆盖的默认构造函数的作用:github.com/jashkenas/backbone/blob/master/backbone.js#L338。请注意,它会创建 attributes 对象,当您的代码在 model2.set() 发生故障时,该对象会丢失
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 2020-08-17
    相关资源
    最近更新 更多