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 #
具体来说,我想知道我是否对 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()
I'm new to CoffeeScript, and I seem to be having trouble with the syntax for calling methods.
Here's the Card model:
class exports.Card extends Backbone.Model
defaults:
pip: '4'
suit: '♠'
color: 'b'
rows: ->
rows =
'4': [2, 0, 2]
rows[@pip]
And the relevant portion of the template:
<ul class="col cols-<%= @card.rows()[0] %>">
which is giving me the error Uncaught TypeError: Object #<Object> has no method 'rows'
Specifically, I'm wondering if I'm using incorrect syntax for the rows method of Card or if I'm just misunderstanding something. Thanks in advance!
Update:
For some reason, @card.property
always works fine, but @card.any_method()
never does. I've gotten around this at the moment by using properties, but I'd love it if someone was able to explain this behavior. Thanks again!
Update 2:
I'm using http://brunchwithcoffee.com if it's a help to anyone, and here's the main.coffee
file to show how the @card
instance is being created and passed to the view.
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的方法调用语法是正确的。 CoffeeScript 的相关规则是:
对于使用参数调用的方法调用,括号是可选的,即
或
对于不带参数调用的方法调用,需要括号,即
要查看其工作原理,请尝试在 CoffeeScript 站点上的“Try CoffeeScript”编辑器上运行以下代码:
由于您的方法调用语法似乎是正确的问题可能是 @card 变量不是exports.Card 类的实例。
Your method calling syntax is correct. The relevant rules for CoffeeScript are:
Parenthesis are optional for method calls invoked with arguments ie
or
Parenthesis are required for method calls invoked with no arguments ie
To see how this works try running the following code on the 'Try CoffeeScript' editor on the CoffeeScript site:
Since your method call syntax is correct it seems likely that the problem is that the @card variable is not an instance of the exports.Card class.
问题是
pip
不是Card
实例的属性;它是Card::defaults
的属性,因此 Backbone 将其设为Card
实例的属性,而不是属性嗯>。 访问pip
属性您可以使用或直接
。这种区别的原因是,在 JavaScript 中,无法监视属性的更改,而 Backbone 需要执行此操作才能分派事件。 (例如,如果您使用
card.set 'pip'
修改pip
,则 Backbone 会触发“change”
事件。)因此,您的如果您只更改
rows
方法的最后一行,代码应该可以正常工作:(注意:某些 JS 环境支持 Getters/setters,这将允许你绘制地图
card.pip = ...
到card.set 'pip', ...
请参阅 John Resig 的文章 这里。Backbone 不使用这种方法,因为它的目标是与所有现代浏览器兼容。)The problem is that
pip
isn't a property of theCard
instance; it's a property ofCard::defaults
, so Backbone then makes it an attribute of theCard
instance—not a property. You can access thepip
attribute withor directly as
The reason for this distinction is that, in JavaScript, there's no way to monitor a property for changes, which Backbone needs to do in order to dispatch events. (If you modify
pip
withcard.set 'pip'
, then Backbone fires a"change"
event, for instance.)So, your code should work fine if you just change the last line of the
rows
method:(Note: Getters/setters are supported in some JS environments, which would allow you to map
card.pip = ...
tocard.set 'pip', ...
See John Resig's article on it here. Backbone doesn't use this approach because it aims to be compatible with all modern-ish browsers.)终于弄清楚了——我忘记了模板中引用的
@card
变量并非源自main.coffee
文件——它实际上被转换为 JSON在CardView
中:现在可以理解为什么只有变量起作用而不是方法了 -
@card
实际上是模型实例的 JSON 表示形式。感谢大家的所有建议/澄清——很抱歉犯了愚蠢的错误:P
Finally figured it out--I forgot that the
@card
variable referenced in the template didn't originate from themain.coffee
file--it was actually being converted into JSON in theCardView
here:Now it makes sense why only variables were working and not methods --
@card
was actually a JSON representation of the model instance.Thanks for all the suggestions/clarifications guys--sorry for the dumb mistake :P