Передача аргументов к событиям в магистрали
Во-первых, я выполнил поиск, и ни один ответ на stackru / google не дал мне то, что я хотел.
Вот фрагмент моего кода:
//in the view
this.collection.on("add",triggerthis)
this.collection.add(predefinedModel)
triggerthis: function(a, b, c, d){
//etc.
}
По сути, я хочу иметь возможность передать аргумент при добавлении и получить аргумент в триггере. Это возможно?
Заранее спасибо.
2 ответа
Вы не можете сделать это так, как вы хотите, без использования недокументированных функций.
Если мы посмотрим на Collection#add
мы увидим это:
add: function(models, options) {
//...
for (i = 0, l = add.length; i < l; i++) {
(model = add[i]).trigger('add', model, this, options);
}
//...
}
Обратите внимание на четвертый аргумент trigger
, И если мы посмотрим на документированный интерфейс для trigger
:
спусковой крючок
object.trigger(event, [*args])
Триггеры обратного вызова для данного события или разделенный пробелами список событий. Последующие аргументы для триггера будут переданы обратным вызовам событий.
Итак add
будет называть слушателей как f(model, collection, options)
где options
та же options
что вы передали Collection#add
, В результате, если вы сделаете это:
this.collection.add(predefinedModel, { undocumented: 'arguments' })
тогда вы можете сделать это в вашем обратном вызове:
triggerthis: function(model, collection, options) {
console.log(options.undocumented);
}
Демо: http://jsfiddle.net/ambiguous/bqWwQ/
Конечно, вы можете туннелировать весь массив или объект через options
сюда.
Третий аргумент в пользу "add"
события не документированы (по крайней мере, я не могу их найти), ближе всего к документации по этому вопросу есть примечание в записи 0.3.3:
Вездесущий
options
Аргумент теперь передается в качестве последнего аргумента для всех"change"
События.
Я бы не рекомендовал такой подход, но он есть, если он вам нужен; вам, конечно, нужно будет охватить это в вашем наборе тестов, и вы должны быть уверены, что вы не используете какие-либо ключи в options
что будет использовать Backbone.
Более безопасный подход - добавить некоторые дополнительные свойства к модели:
model.baggage = { some: 'extra stuff };
а затем очистить это в обратном вызове:
triggerthis: function(model, collection) {
var baggage = model.baggage;
delete model.baggage;
//...
}
Демо: http://jsfiddle.net/ambiguous/M3UaH/
Вы также можете использовать различные обратные вызовы для разных целей или передавать свои дополнительные параметры как полноценные атрибуты модели.
Есть также _.bind
:
this.collection.on("add", _.bind(function(collection, model, extra) { ... }, context, collection, model, 'whatever you want'));
но это будет связывать аргументы слева направо, поэтому вам нужно будет указать все аргументы, которые понадобятся вашему обратному вызову.
Если значения, передаваемые в функцию, всегда одинаковы, вы можете частично применить ее, используя _.bind
(или родной Function.bind
если доступно)
Например, где вы привязываете обработчик к add
(при условии, triggerThis
это метод на ваш взгляд):
this.collection.on('add', _.bind(this.triggerThis, this, a, b, c, d));
Определение triggerThis
:
triggerThis: function(a, b, c, d /*, model, collection, options - if you need them*/) {
...
}
Если вы хотите передать аргументы отдельному вызову add, вы можете использовать второй options
параметр для add
а затем обработать это в вашем обработчике событий.
Например
this.collection.on('add', this.triggerThis, this);
this.collection.add(model, {
someCustomValue: 'hello';
});
Тогда в вашем обработчике:
triggerThis: function(model, collection, options) {
var val = options.someCustomValue;
...
}