Синтаксис вызова метода в CoffeeScript - PullRequest
6 голосов
/ 26 августа 2011

Я новичок в 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 или я просто что-то неправильно понимаю. Заранее спасибо!

Обновление:

По какой-то причине @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 ]

14 голосов
/ 26 августа 2011

Ваш синтаксис вызова метода правильный. Соответствующие правила для CoffeeScript:

  • Скобки являются необязательными для вызовов методов, вызываемых с аргументами, например

    object.method 1,2 
    

    или

    object.method(1,2)
    
  • Скобки требуются для вызовов методов, вызываемых без аргументов, т.е.

    object.method()
    

Чтобы увидеть, как это работает, попробуйте запустить следующий код в редакторе «Try CoffeeScript» на сайте CoffeeScript:

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

(new A()).method();

Поскольку синтаксис вызова вашего метода правильный, вероятно, проблема в том, что переменная @card не является экземпляром класса exports.Card.

1 голос
/ 26 августа 2011

Проблема в том, что 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, что позволяет сопоставлять card.pip = ... с card.set 'pip', ... См.Статья Джона Ресига об этом здесь . Backbone не использует этот подход, потому что он стремится быть совместимым со всеми современными браузерами.)

0 голосов
/ 27 августа 2011

Наконец-то понял - я забыл, что переменная @card, на которую есть ссылка в шаблоне, произошла не из файла main.coffee - она ​​на самом деле конвертируется в JSON в CardView здесь:

cardTemplate = require('templates/card')

class exports.CardView extends Backbone.View
  tagName:   'div'
  className: 'card'

  render: ->
    $(@el).html cardTemplate(card: @model.toJSON())
    @

Теперь имеет смысл, почему работали только переменные, а не методы - @card был фактически JSON-представлением экземпляра модели.

Спасибо за все предложения / разъяснения, ребята - извинитеза глупую ошибку: P

...