Rails + Backbone.js: возникают проблемы с доступом к видимым объектам - PullRequest
0 голосов
/ 19 ноября 2011

получил проблему в течение нескольких дней с магистралью и не может найти способ ее решить или найти решение для stackoverflow.

Я использую Rails 3.1 + последняя магистраль (+ coffeescript):

Вот один из моих видов в качестве примера (та же проблема во всех из них):

Blog.Views.Payment ||= {}

class Blog.Views.Payment.PaymentView extends Backbone.View
  className:  'payment_method'
  tagName:    'td'
  events:
    'click #renderPayment':  'renderPayment'

  initialize: ->
    # CAN'T access @options.payment_methods here 
    @options.payment_methods.bind(###stuff###)

  render: ->
    # CAN'T access @options.payment_methods here either...
    $(@el).html ("### something with #{@options.payment_methods or @options.payment_methods.model}")
    return @

  updateView: ()->
    # updating view stuff...

  renderPayment:  ->
    # ACCESSING @options.payment_methods fine here!!!
    if ($("#payment_details").length == 0)
      $(@el).append("<ul id='payment_details'>
                       <li id='payment_type'>#{@options.payment_methods.get(1).get('payment_type')}</li>
                     </ul>
                       ").effect("highlight", 700)

В первых двух случаях, когда я запускаю пример, браузер сообщает мне, что @options.payment_methods не определен, третий случай работает нормально.

Во-вторых, я не могу получить доступ к элементам DOM, которые уже «жестко закодированы» на странице и не созданы Javascript.Я знаю причину этого и читал множество постов здесь, в Stackoverflow, но я не мог найти какое-либо решение для работы.Любые советы приветствуются.

С наилучшими пожеланиями, Фил

РЕДАКТИРОВАТЬ: Кажется, что это имеет какое-то отношение к времени доступа объектов на странице, аналогично доступу в жестком кодеDOM-элементы страницы.Если я отредактирую свое представление следующим образом, я больше не смогу получить доступ к @ options.payment_methods, даже если раньше мне удавалось сделать это в коде.

# changed "renderPayment" to "$(document).ready" or just "$" in coffeescript
$  ->
  # ACCESS NOT possible anymore
  if ($("#payment_details").length == 0)
    $(@el).append("<ul id='payment_details'>
                     <li id='payment_type'>#{@options.payment_methods.get(1).get('payment_type')}</li>
                   </ul>
                     ").effect("highlight", 700) 

EDIT2: добавлен соответствующий файл маршрутизатора: (этотЭто просто модифицированная версия примера драгоценного камня Backbone-rails "Блог")

class Blog.Routers.PostsRouter extends Backbone.Router
  initialize: (options) ->
    @posts = new Blog.Collections.PostsCollection()
    @posts.reset options.posts

    # ... other collections

    # fetch payment_methods collection
    @payment_methods = new Blog.Collections.PaymentMethodsCollection()
    @payment_methods.reset options.payment_methods
    @payment_methods.fetch()

    @model = ({posts: @posts, mails: @mails, addresses: @addresses, purchases: @purchases, payment_methods: @payment_methods})

  routes:
    "/new"            : "newPost"
    "/index"          : "index"
    "/:id/edit"       : "edit"
    "/:id"            : "show"
    ".*"              : "index"


  # main view
  index:  ->

    # render Product Info View
    @view = new Blog.Views.Product.ProductView(purchases: @purchases)
    $("#product_1").html(@view.render().el)

    ##### view etc.

    # render Payment View
    @view5 = new Blog.Views.Payment.PaymentView(payment_methods: @payment_methods)
    $("#customer_1").append(@view5.render().el)

   ### other views...

И моя модель оплаты:

class Blog.Models.PaymentMethod extends Backbone.Model
  paramRoot: 'payment_method'

  defaults:
    payment_type: null
    # ...

class Blog.Collections.PaymentMethodsCollection extends Backbone.Collection
  model: Blog.Models.PaymentMethod
  url: '/payment_methods'

Ответы [ 2 ]

0 голосов
/ 20 ноября 2011

Опции передаются в метод инициализации представления. Таким образом, вы можете получить к ним прямой доступ.

initialize: (options) ->
  # Now you have options
  options.payment_methods.bind(###stuff###)

Вызов @options в render() должен быть в порядке, за исключением случая, когда рендеринг не вызывается в контексте вашего представления, то есть из какого-то другого обратного вызова. Чтобы исправить это, определите render жирной стрелкой, и она всегда будет вызываться в контексте представления.

render: =>
  $(@el).html( ...etc...)

Если вы хотите получить доступ к элементам, которые уже находятся на странице, то вам нужно сделать несколько вещей. Самое главное, передать элемент DOM в el конструктору представления, и ваше представление «захватит» и будет владеть этим элементом. Например ..

view = new Blog.Views.Payment.PaymentView(
  el: $("#product_whatever").get(0)
)

Затем в этом представлении вы хотите охватить найденные вами jQuery элементом представления. Например:

render: =>
  $(@el).find('div.somewhere_else').html("change this")

Сокращенный код для этого в coffeescript:

@$('div.somewhere_else').html(...)

Удачи

0 голосов
/ 19 ноября 2011

Вам действительно нужно посмотреть и понять разницу между -> и =>. Похоже, что большинство методов в ваших классах используют ->, тогда как они должны использовать =>. Где бы вы ни использовали @something, это действительно ярлык на this.something, а => гарантирует, что this действительно то, что вы ожидаете. С ->, this будет привязан к тому, что есть в функции, которая делает вызов, а не к вашему экземпляру класса.

...