Backbone: Получение / сохранение коллекции и модели и т. Д. Статус

Созданный на 24 янв. 2013  ·  9Комментарии  ·  Источник: jashkenas/backbone

Чтобы узнать, была ли коллекция заполнена или заполняется, может быть что-то вроде


collection.fetch();
collection.isFetching()===true; // display loading 

(collection.isFetching()===false; && collection.length) // display no records found

Реальный вариант использования (упрощение, объекты передаются глубоко в систему):

javascript() // somewhere in the code collection = new MyCollection(); // somewhere else in the code view = new MyView({collection:collection}); // and somewhere else in the code collection.fetch();

представление прослушивает сигналы сбора и отображает либо загрузка / отсутствие записей / список записей

для модели может быть даже функция сохранения / удаления / обновления

question

Самый полезный комментарий

@braddunbar , @caseywebdev идея состоит в том, чтобы разделить эти две части. (view должен иметь возможность получать коллекцию в любом состоянии, а не только _'clean'_ collection)
Я знаю, что могу сделать это с помощью сигналов, но во многих случаях это невозможно. Порядок действий имеет значение

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

Рассмотрим пример, в котором ваше представление получает произвольную коллекцию. Эта коллекция может быть либо _fetched_, _fetching_, или _unfetched_, когда она передается в представление (tl: dr см. Пример 3) .

Пример 1 (где будут работать сигналы)

collection = new Backbone.Collection();
view = new Backbone.View({collection:collection});
view.render();
// what should the view render ?
collection.fetch() // now sync signal gets sent

Пример 2 (представление уже загружено, но коллекция пустых, сигналы также будут работать)

collection = new Backbone.Collection();
collection.fetch();  // now sync signal gets sent
// after fetch completes
// view won't be able to receive 'sync' signal
view = new Backbone.View({collection:collection}); 
view.render(); 
// at this point collection.length == 0. 
// I guess the view can listen to 'sync' and then render 'empty' 

Пример 3 (самое главное, сигналы работать не будут)

collection = new Backbone.Collection();
collection.fetch();  // now 'request' signal gets sent, but it is pending
// view won't be able to receive 'request' signal
view = new Backbone.View({collection:collection}); // at this point collection.length == 0
// view did not receive the 'request' signal, therefore has no idea that the collection is fetching
// and the view should render  'loading'
// after 2 seconds, 'sync' signal gets sent

Представление не должно предполагать, что если collection.length == 0, то он не получен.
Представление также не должно предполагать, что ему передана коллекция в невыгруженном состоянии (или в любом другом состоянии).

Если мы хотим отделить коллекцию от представления, тогда представление должно знать, что такое состояние коллекции.

то же самое и с моделью

Все 9 Комментарий

Привет @ g00fy-! Я бы рекомендовал вам использовать для этой цели события "request" и "sync" . Что вы думаете?

collection.on('request', function() {
  // loading...
}).on('sync', function() {
  // display records or "none found"
});
collection.fetch();

_Edit - я имел в виду событие "request" , а не "fetch" ._

Я думаю, это отличная идея, @braddunbar!

Спасибо @caseywebdev! :)

Сообщите нам, если это не сработает для вас @ g00fy-.

@braddunbar , @caseywebdev идея состоит в том, чтобы разделить эти две части. (view должен иметь возможность получать коллекцию в любом состоянии, а не только _'clean'_ collection)
Я знаю, что могу сделать это с помощью сигналов, но во многих случаях это невозможно. Порядок действий имеет значение

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

Рассмотрим пример, в котором ваше представление получает произвольную коллекцию. Эта коллекция может быть либо _fetched_, _fetching_, или _unfetched_, когда она передается в представление (tl: dr см. Пример 3) .

Пример 1 (где будут работать сигналы)

collection = new Backbone.Collection();
view = new Backbone.View({collection:collection});
view.render();
// what should the view render ?
collection.fetch() // now sync signal gets sent

Пример 2 (представление уже загружено, но коллекция пустых, сигналы также будут работать)

collection = new Backbone.Collection();
collection.fetch();  // now sync signal gets sent
// after fetch completes
// view won't be able to receive 'sync' signal
view = new Backbone.View({collection:collection}); 
view.render(); 
// at this point collection.length == 0. 
// I guess the view can listen to 'sync' and then render 'empty' 

Пример 3 (самое главное, сигналы работать не будут)

collection = new Backbone.Collection();
collection.fetch();  // now 'request' signal gets sent, but it is pending
// view won't be able to receive 'request' signal
view = new Backbone.View({collection:collection}); // at this point collection.length == 0
// view did not receive the 'request' signal, therefore has no idea that the collection is fetching
// and the view should render  'loading'
// after 2 seconds, 'sync' signal gets sent

Представление не должно предполагать, что если collection.length == 0, то он не получен.
Представление также не должно предполагать, что ему передана коллекция в невыгруженном состоянии (или в любом другом состоянии).

Если мы хотим отделить коллекцию от представления, тогда представление должно знать, что такое состояние коллекции.

то же самое и с моделью

@ g00fy Если вы не можете просто fetch коллекцию после отправки ее в представление, установите флаг fetching или что-то подобное в вашей коллекции.

collection.on({
  request: function () { this.fetching = true; },
  'sync error': function () { this.fetching = false; }
});

Теперь ваше представление может получить доступ к this.collection.fetching а также дождаться this.collection чтобы запустить событие sync или error .

@caseywebdev
Запрос может быть прерван или могут быть отправлены сразу два запроса.

// example 1
collection.fetch().abort()  // and collection.fetching == true
// example 2 - don't care about abort();
collection.fetch();
collection.fetch();
// 1st request compleated
!!collection.fetching == false // but the 2nd request is pending - should it be loading or not?
// 2nd request completed

Решением этого будет подключение do deferred xhr

collection.on({
    'request':function(model,xhr){ 
        this.fetching = true; 
        xhr.fail(function(){this.fetching = false }.bind(this));
    },
    'sync error': function () { this.fetching = false; }
});

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

если бы все подобные улучшения были реализованы, кодовая база BB была бы раздутой.

Я думаю, дело не столько в вздутии живота, сколько в подходе. Есть много разных способов обработки одновременных запросов. Backbone предоставляет вам примитивы, необходимые для их обработки, а затем уходит с дороги.

@ g00fy - вы можете попробовать написать конечный автомат для ваших целей. У Chaplin.js есть тот, который должно быть довольно легко воспроизвести, а также есть ifandelse / machina.js (см. блоге ), который может соответствовать вашему конкретному варианту использования.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги