Передача аргументов событиям в backbone

прежде всего, я сделал некоторый поиск и не ответил на stackoverflow/google предоставил мне то, что я хотел.

вот фрагмент моего кода:

//in the view
this.collection.on("add",triggerthis)
this.collection.add(predefinedModel)
triggerthis: function(a, b, c, d){
    //etc.
}

в принципе, я хочу иметь возможность передать аргумент на add и получить аргумент в triggerthis. Возможно ли это?

спасибо заранее.

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 этот позвоночник будет использовать.


более безопасным подходом было бы прикрепить некоторые дополнительные свойства к модели:

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'));

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

демо:http://jsfiddle.net/ambiguous/jUpJz/


если значения, переданные функции всегда одинаковы, вы можете частично применить он с помощью _.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 а затем в обработчике событий.

Э. Г.

this.collection.on('add', this.triggerThis, this);
this.collection.add(model, {
  someCustomValue: 'hello';
});

затем в обработчике:

triggerThis: function(model, collection, options) {
  var val = options.someCustomValue;
  ...
}