Почему backbone.js возвращает пустой массив при доступе к моделям? - PullRequest
7 голосов
/ 20 февраля 2012

У меня есть маршрутизатор, который обращается к его коллекции. Мой цикл for не перебирал модели, поэтому я попытался зарегистрировать коллекцию, чтобы увидеть, что она вернула. Оказывается, когда я регистрирую коллекцию напрямую, я вижу все модели, как и ожидалось. Но если я попытаюсь зарегистрировать атрибут models в коллекции, я получу пустой массив! Это не имеет смысла. Эти строки непосредственно следуют друг за другом. Я попытался изменить порядок и получил тот же результат.

console.log(this.collection);
=> Shots
    _byCid:    Object
    _byId:     Object
    length:    15
    models:    Array[15]
    __proto__: Shots
    ...

console.log(this.collection.models);
=> []

console.log(this.collection.length);
=> 0

Почему это случилось?

Вот код, который находится в маршрутизаторе, чтобы дать лучший контекст того, где этот код запускается:

# Routers
class Draft.Routers.Shots extends Backbone.Router
  routes:
    ''            : 'index'
    'shots/:id'   : 'show'

  initialize: ->
    @collection = new Draft.Collections.Shots()
    @collection.fetch()

  index: ->
    console.log @collection
    console.log @collection.models

Ответы [ 3 ]

5 голосов
/ 20 февраля 2012

Джим,

Это не решит твою проблему - ты уже решил это. Но это объясняет, почему вы видите вывод консоли.

Когда вы запускаете console.log (this), вы выводите сам объект, и консоль связывает ссылки (указатели, если хотите) на внутренние переменные.

Когда вы смотрите на это в консоли, в то время, когда console.log (этот) запускает область моделей пуста, но в то время, когда вы смотрите на журналы, коллекция закончила загрузку моделей, и переменная внутреннего массива обновлена, И ссылка на эту переменную в журнале объектов показывает текущее содержимое.

По сути, в console.log (this) переменная inner models продолжает свою обычную жизнь, и консоль отображает текущее состояние во время просмотра, а не во время вызова. При использовании console.log (this.models) массив выгружается как есть, ссылки не сохраняются, а все внутренние значения выводятся по одному ..

Такое поведение довольно просто воспроизвести за короткий промежуток времени, см. Эту скрипку .. http://jsfiddle.net/bendog/XVkHW/

2 голосов
/ 20 февраля 2012

Я обнаружил, что мне нужно прослушать сброс коллекции.Поэтому вместо того, чтобы передавать модель в представление, я создал другое представление, ожидающее коллекцию, и прослушал событие 'reset', чтобы запустить 'render' для представления.

# Routers
class Draft.Routers.Shots extends Backbone.Router
  routes:
    ''            : 'index'
    'shots/:id'   : 'show'

  initialize: ->
    @collection = new Draft.Collections.Shots()
    @collection.fetch()

  index: ->
    view = new Draft.Views.Desktop(collection: @collection)

# Views
class Draft.Views.Desktop extends Backbone.View
  el: $("body")

  initialize: ->
    @collection.on("reset",@render,this)

  render: ->
    console.log @collection
    console.log @collection.length
0 голосов
/ 24 мая 2013

Вы можете использовать обещание.(.done подойдет)

@collection.fetch().done =>
  for model in @collection.models
    console.log model

это даст вам модели @ collection, выбранные и готовые к работе.

или если вам не нужно заставлять приложение ждать,

@collection.on 'sync', =>
  for model in @collection.models
    console.log model

И то, и другое позволит вам делать то, что вы хотите.

...