Событие изменения магистрали для имен атрибутов, содержащих пробел

#backbone.js #backbone-events

#backbone.js #магистральные события

Вопрос:

Как я могу добавить событие для этого имени атрибута: Lorem Ipsum ?

Я пытался

 this.model.on("change:Lorem Ipsum")
  

но это дает мне два события:

  • изменение:Lorem
  • Ipsum

Комментарии:

1. Ок .. Только что нашел это в документации: «В связи с тем, что Events принимает списки событий, разделенные пробелами, имена атрибутов не должны содержать пробелов». Они действительно должны изменить разделенный пробелами список событий на разделенный запятыми: (

2. вы просто не можете назвать атрибут таким именем, вы получите синтаксическую ошибку

3. Да, я могу. Я использую его сейчас.

4. Нет, вы не можете — вы получите синтаксическую ошибку SyntaxError: отсутствует: после идентификатора свойства. Вы можете открыть консоль и проверить это или проверить эту скрипку — jsfiddle.net/qDX95

5. Я не использую значения по умолчанию. Я использую это в течение последних 2/3 месяцев. И это первый раз, когда возникает проблема с именем атрибута с пробелом. Кроме того, я не использую методы get или set, потому что у меня вложенная (немного сложная) модель. В любом случае спасибо 🙂

Ответ №1:

Как вы отметили в комментариях, в документации указано, что из-за того, что Events принимает списки событий, разделенных пробелами, имена атрибутов не должны содержать пробелов.1

Однако, если вы готовы пойти на некоторый риск в отношении того, как будущие версии Backbone будут обрабатывать это, покопаться в исходном коде Backbone и поставить под угрозу свою работоспособность, вы можете переопределить Events механизм в вашей модели :

 var M = Backbone.Model.extend({
    on: function(name, callback, context) {
        if (name!=='change:Lorem Ipsum') {
            return Backbone.Model.prototype.on.call(this,name, callback, context);
        }

        this._events = this._events || {};
        this._events[name] = this._events[name] || [];
        this._events[name].push({
            callback: callback, 
            context: context, 
            ctx: context || this
        });
        return this;
    },
    trigger: function(name) {
        if (name!=='change:Lorem Ipsum') {
            return Backbone.Model.prototype.trigger.apply(this, arguments);
        }

        var events = this._events amp;amp; this._events[name];
        if (!events) return this;
        var ev, i = -1, l = events.length, args = [].slice.call(arguments, 1);

        while (  i < l) (ev = events[i]).callback.apply(ev.ctx, args);        
        // I skipped the all event

        return this;
    }
});
  

Идея состоит в том, чтобы самостоятельно обрабатывать регистрацию и отправку события на основе текущей реализации модуля Events. Вам также придется изменить другие методы, если они вам понадобятся.

После этого установка Lorem Ipsum атрибута будет работать как «ожидалось»:

 var m = new M();
m.on("change", function(model) {
     console.log('change', model.changedAttributes());
});
m.on("change:Lorem Ipsum", function(model) {
    console.log('change:Lorem Ipsum', model.changedAttributes());
});

m.set('Lorem Ipsum', 'dolor sit amet');
  

Смотрите http://jsfiddle.net/nikoshr/44m7L / для демонстрации

1 http://backbonejs.org/#Model-attributes

Комментарии:

1. Вау, большое вам спасибо! Это здорово! Теперь я понимаю, что использовать атрибуты, содержащие пробел, — не лучшая практика. Некоторые встроенные функции не будут работать. Как указано пользователем выше, функция defaults выдаст синтаксическую ошибку. Я не буду использовать вашу реализацию, это действительно немного рискованно, я нашел более безопасное решение. Еще раз спасибо, что рассказали кое-что об исходном коде магистрали 🙂

Ответ №2:

LoremIpsum должен содержать одно слово.

this.model.on(«изменить:LoremIpsum», YourFunction)

Комментарии:

1. ДА. Спасибо 🙂 Было бы здорово, если бы они могли изменить это в следующих версиях!