2011-08-26 12 views
6

Jestem nowy w CoffeeScript i wydaje mi się, że mam problem ze składnią wywołań metod.Metoda Składnia wywołania w CoffeeScript

Oto model karty:

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

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

a odpowiednimi część szablonu:

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

który daje mi błąd Uncaught TypeError: Object #<Object> has no method 'rows'

Konkretnie zastanawiam się, czy I "Używam niepoprawnej składni dla metody wierszy karty lub jeśli coś nie rozumiem. Z góry dziękuję!

Aktualizacja:

Z jakiegoś powodu, @card.property zawsze działa dobrze, ale @card.any_method() nigdy nie robi. W tej chwili obejrzałem to, korzystając z właściwości, ale bardzo bym chciał, gdyby ktoś był w stanie wyjaśnić to zachowanie. Dzięki jeszcze raz!

Aktualizacja 2:

Używam http://brunchwithcoffee.com czy jest to pomoc dla każdego, a oto plik main.coffee aby pokazać, jak instancja @card jest tworzony i przekazywany do widzenia.

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() 
+1

W jaki sposób utworzono "@ card"? Jako 'nowa karta eksportowa'? Czy przechodzi test '@ card instanceof exports.Card'? –

+0

zaktualizowano, aby pokazać, jak tworzona jest karta @ label. – mportiz08

+0

Wskazówka dotycząca stylu: Możesz wpisać '{Card} = wymagaj 'models/card_model'' zamiast' Card = require (' models/card_model '). –

Odpowiedz

14

Twoja składnia wywoływania metody jest poprawna. Odpowiednie zasady coffeescript są:

  • Parenthesis są opcjonalne dla wywołań metod przywołanych argumentów tj

    object.method 1,2 
    

    lub

    object.method(1,2) 
    
  • nawiasach są wymagane dla wywołań metod przywołanych bez argumentów tj.

    object.method() 
    

Aby zobaczyć jak to działa spróbuj uruchomić następujący kod na „Spróbuj coffeescript” edytor na miejscu coffeescript:

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

(new A()).method(); 

Ponieważ składnia sposób połączenie jest poprawne wydaje się prawdopodobne, że problem jest, że Zmienna @card nie jest instancją klasy exports.Card.

+0

hm, jestem naprawdę zdezorientowany - @ card jest zdecydowanie instancją klasy Card, ponieważ jestem w stanie bezpiecznie "<% = @ card.pip%>' jedną z poprzednich linii w widoku – mportiz08

+0

miałeś rację - @ card była w rzeczywistości toJSON() odpowiednikiem tego, co myślałem, że to było – mportiz08

1

Problem polega na tym, że pip nie jest własnością instancji Card; jest to własność Card::defaults, więc Backbone następnie nadaje jej atrybut z instancji Card - nie jest to właściwość .Możesz uzyskać dostęp do atrybutu pip z

card.get 'pip' 

lub bezpośrednio jako

card.attributes.pip 

Przyczyną tej różnicy jest to, że w JavaScript, nie ma sposobu, aby monitorować nieruchomości do zmian, które Backbone musi zrobić w celu wysyłania zdarzeń. (Jeśli modyfikować pip z card.set 'pip', następnie Backbone pożary zdarzenie "change", na przykład.)

Tak Twój kod powinien działać dobrze, jeśli tylko zmienić ostatnią linię metody rows:

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

(. Uwaga: Pochłaniacze gazów/ustawiaczy są obsługiwane w środowiskach niektóre JS, który pozwoli Ci mapa card.pip = ... art card.set 'pip', ... zobacz Jana Resig nad tym here Backbone nie korzysta z tej metody, ponieważ ma być zgodny . Ze wszystkimi przeglądarkami nowoczesny-owski)

+0

dzięki za wyjaśnienie właściwości w stosunku do atrybutów, ale nadal otrzymuję błąd "nie ma metody" podczas wywoływania dowolnej metody na @ karta – mportiz08

0

końcu zorientowaliśmy się - zapomniałem, że @card zmienna mowa w szablonie nie pochodzą z akt main.coffee - to faktycznie przekształcana JSON w CardView tutaj:

cardTemplate = require('templates/card') 

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

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

teraz to ma sens, dlaczego tylko zmienne roboczą, a nie metody - @card faktycznie reprezentacja JSON instancji modelu.

Dzięki za wszystkie sugestie i wyjaśnienia - przepraszamy za głupi błąd: P

Powiązane problemy