CoffeeScript中的方法调用语法

时间:2011-08-26 05:46:25

标签: javascript syntax backbone.js coffeescript

我是CoffeeScript的新手,我似乎在调用方法的语法方面遇到了麻烦。

这是卡片型号:

class exports.Card extends Backbone.Model
  defaults:
    pip:   '4'
    suit:  '♠'
    color: 'b'

  rows: ->
    rows =
      '4': [2, 0, 2]
    rows[@pip]

模板的相关部分:

<ul class="col cols-<%= @card.rows()[0] %>">

这给了我错误Uncaught TypeError: Object #<Object> has no method 'rows'

具体来说,我想知道我是否对Card的rows方法使用了错误的语法,或者我只是误解了一些东西。提前谢谢!

更新

出于某种原因,@card.property始终正常,但@card.any_method()永远不会。我现在通过使用属性来解决这个问题,但如果有人能够解释这种行为,我会很喜欢它。再次感谢!

更新2:

如果它是对任何人的帮助,我正在使用http://brunchwithcoffee.com,这里是main.coffee文件,用于显示如何创建@card实例并将其传递给视图。

window.app = {}
app.routers = {}
app.models = {}
app.collections = {}
app.views = {}

Card = require('models/card_model').Card
MainRouter = require('routers/main_router').MainRouter
HomeView = require('views/home_view').HomeView
CardView = require('views/card_view').CardView

# app bootstrapping on document ready
$(document).ready ->
  app.initialize = ->
    app.routers.main = new MainRouter()
    app.views.home = new HomeView()
    app.views.card = new CardView(model: new Card(color: 'r', suit: '♥', pip: '7'))
    app.routers.main.navigate 'home', true if Backbone.history.getFragment() is ''
  app.initialize()
  Backbone.history.start()

3 个答案:

答案 0 :(得分:14)

您的方法调用语法是正确的。 CoffeeScript的相关规则是:

  • 对于使用参数调用的方法调用,括号是可选的,即

    object.method 1,2 
    

    object.method(1,2)
    
  • 无参数调用的方法调用需要使用括号,即

    object.method()
    

要了解其工作原理,请尝试在CoffeeScript网站上的“Try CoffeeScript”编辑器中运行以下代码:

class A
  method: ->
    console.log "A"

(new A()).method();

由于您的方法调用语法是正确的,因此问题似乎是@card变量不是exports.Card类的实例。

答案 1 :(得分:1)

问题是pip不是Card实例的属性;它是Card::defaults的属性,因此Backbone使其成为Card实例的属性 - 而不是属性。您可以使用

访问pip属性
card.get 'pip'

或直接作为

card.attributes.pip

这种区别的原因在于,在JavaScript中,没有办法监视属性的变化,Backbone需要这样做才能分派事件。 (如果您使用pip修改card.set 'pip',则Backbone会触发"change"事件。)

因此,如果您只是更改rows方法的最后一行,您的代码应该可以正常工作:

rows: ->
  rows =
    '4': [2, 0, 2]
  rows[@get 'pip']

注意: 某些 JS环境支持Getters / setter,这样您就可以将card.pip = ...映射到card.set 'pip', ...。请参阅John Resig的关于它的文章here .Backbone不使用这种方法,因为它旨在与所有现代浏览器兼容。)

答案 2 :(得分:0)

最后弄清楚了 - 我忘了模板中引用的@card变量不是来自main.coffee文件 - 它实际上是在{{1}中转换为JSON的这里:

CardView

现在有意义的是为什么只有变量工作而不是方法 - cardTemplate = require('templates/card') class exports.CardView extends Backbone.View tagName: 'div' className: 'card' render: -> $(@el).html cardTemplate(card: @model.toJSON()) @ 实际上是模型实例的JSON表示。

感谢所有建议/澄清人员 - 抱歉愚蠢的错误:P