Как выполнить массовый поиск или создание с помощью ember.js? Это было бы просто сделать синхронно (foreach... continue, если существует). Но работа с асинхронным хранилищем ember создает много накладных расходов на отслеживание состояния операции.
В частности, у меня есть переменная для отслеживания количества объектов, ожидающих обработки (createIfNotExistTaskCounter
), поэтому я могу проверить, когда хранилище закончило работу со всеми объектами, которые нужно сохранить. И я использую массив для отслеживания элементов, хранящихся до сих пор (createIfNotExistQueue
) - я не могу позволить магазину справиться с этой задачей, потому что я не могу рассчитывать на то, что элемент будет найден после его сохранения.
Вот мое лучшее решение ниже (также на JS Bin). Есть ли более простой способ сделать это?
App = Ember.Application.create({});
App.LSAdapter = DS.LSAdapter.extend({
namespace: 'whitespace'
});
App.Store = DS.Store.extend({
adapter: App.LSAdapter
});
App.Fruit = DS.Model.extend({
name: DS.attr("string")
});
App.IndexRoute = Ember.Route.extend({
createIfNotExistTaskCounter: 0, // store number of items waiting to be processed
createIfNotExistQueue: [], // store a list of the items being added, to prevent duplicate adds
setupController: function(controller) {
/* This is a simplified version of a real task I'm trying to acomplish. The code adds a list of objects to the store, only creating them if they don't exist. After the list has been processed, the contents of the store are shown.
To achieve this end I've used a counter and a queue to keep track of the operations' state. Is there a simpler way to do this? These overheads seem excessive for such a straightforward bulk insert operation.
*/
var fruitToStore = ["apple", "pear", "banana", "apple"],
store = this.get('store');
this.set('createIfNotExistTaskCounter', fruitToStore.length);
for(var i=0; i<fruitToStore.length; i++) {
this.createIfNotExist(fruitToStore[i]);
}
},
createListener: function() {
if(this.get('createIfNotExistTaskCounter') !== 0) return;
this.get('store').find('fruit').then(function(results) {
// should only print three fruits, one of each type
for (var i = 0; i < results.content.length; i++) {
console.log(results.content[i].get('name'));
};
});
}.observes('createIfNotExistTaskCounter'),
createIfNotExist: function(f) {
var store = this.get('store'),
queue = this.get('createIfNotExistQueue'),
that = this;
// prevent duplicate records being created by adding every (distinct) item to a queue
// the queue is used because there seems to be no way to tell if an item is already (asynchonously) being found / created / saved
if(queue.indexOf(f) !== -1) {
that.decrementProperty('createIfNotExistTaskCounter');
return;
}
queue.push(f);
// find or create
store.find('fruit', {name: f}).then(function(results) {
// found...
if(results.get('length') !== 0) {
that.decrementProperty('createIfNotExistTaskCounter');
return;
}
// ...else create
var fruit = store.createRecord('fruit', {name: f});
fruit.save().then(function() {
that.decrementProperty('createIfNotExistTaskCounter');
}, function() {
console.log("save failed!");
});
});
}
});