Coffee Call Call Syntax

I'm new to CoffeeScript, and I seem to be having problems with the syntax for calling methods.

Here's the map model:

class exports.Card extends Backbone.Model defaults: pip: '4' suit: '♠' color: 'b' rows: -> rows = '4': [2, 0, 2] rows[@pip] 

And the corresponding part of the template:

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

which gives me an Uncaught TypeError: Object #<Object> has no method 'rows' error Uncaught TypeError: Object #<Object> has no method 'rows'

In particular, I am wondering if I am using the wrong syntax for the Card string method or if I just misunderstand something. Thanks in advance!

Update:

For some reason, @card.property always works fine, but @card.any_method() never works. I currently circumvented this using properties, but I would have liked it if someone could explain this behavior. Thanks again!

Update 2:

I use http://brunchwithcoffee.com if this helps anyone, and here is the main.coffee file to show how the @card instance is 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() 
+6
source share
3 answers

Your method call syntax is correct. Relevant rules for CoffeeScript:

  • Parenthesis are optional for method calls called with arguments, i.e.

     object.method 1,2 

    or

     object.method(1,2) 
  • For calls to methods called without arguments, parentheses are required, i.e.

     object.method() 

To see how this works, try running the following code in the Try CoffeeScript editor on the CoffeeScript site:

 class A method: -> console.log "A" (new A()).method(); 

Since your method invocation syntax is correct, it seems likely that the problem is that the @card variable is not an instance of the export.Card class.

+14
source

The problem is that the pip is not an instance of Card ; this is a Card::defaults property, so Backbone then makes it an attribute of Card instance-not a property. You can access the pip attribute with

 card.get 'pip' 

or directly as

 card.attributes.pip 

The reason for this difference is that in JavaScript there is no way to track the change property that the Backbone must execute to dispatch events. (If you change pip with card.set 'pip' , then Backbone fires a "change" event, for example.)

So your code should work fine if you just change the last line of the rows method:

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

( Note: Getters / seters are supported in some JS environments, which allows you to map card.pip = ... to card.set 'pip', ... See John Resig's article on this here . Backbone does not use this approach because it is designed to be compatible with all modern browsers.)

+1
source

Finally I realized this - I forgot that the @card variable referenced by the template was not created from the main.coffee file - it was actually converted to JSON in CardView here:

 cardTemplate = require('templates/card') class exports.CardView extends Backbone.View tagName: 'div' className: 'card' render: -> $(@el).html cardTemplate(card: @model.toJSON()) @ 

Now it makes sense why only variables work, not methods - @card is actually a representation of the JSON model of the model instance.

Thanks for all the suggestions / clarifications, guys - sorry for the stupid mistake: P

0
source

Source: https://habr.com/ru/post/895937/


All Articles