Подтвердить что ты не робот

Как я могу "размазать" события в иерархии "Магистральный вид"?

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

NewsListView = Backbone.View.extend({

    el: $('li#newspane'),

    // This is what I would like to be able to do
    // events: { 'filtered': 'reset' }

    initialize: function() {
        _.bindAll(this);
    },

    render: function() {
    },

    reset: function(){
    }

});

FilterView = Backbone.View.extend({

    el: $('li.filter'),

    initialize: function() {
    },

    render: function() {
    },

    toggleFilter: function() {
    }

});

AllView = Backbone.View.extend({

    initialize: function() {

        this.newsListView = new NewsListView();
        this.filterView = new FilterView();

    }

});

По существу, всякий раз, когда вызывается функция FilterView toggleFilter(), я хотел бы запустить событие под названием filtered или что-то вроде этого, которое затем захватывается NewsListView, которое затем вызывает его reset() функция. Не передавая ссылку объекта NewsListView на мой FilterView, я не уверен, как отправить ему событие. Любые идеи?

4b9b3361

Ответ 2

Возможно, вы сможете это сделать, используя уже имеющиеся функции jquery-событий и свойство основных событий.

Например, вместо этого изнутри вашего подвью:

this.trigger("yourevent", this);

сделайте это вместо:

this.$el.trigger("yourevent", this);

Затем в любом представлении, являющемся родительским, grandparent и т.д. вашего дочернего представления, прослушайте событие в этом представлении $el, указав свойство в объекте событий вида:

events:{
    "yourevent":"yourhandler"
}

и определите обработчик на этом представлении:

yourhandler:function(subview) {
}

Таким образом, представление не обязательно должно знать о том, какие существуют представления потомков, а только тип события, в котором он заинтересован. Если представление, инициирующее событие, уничтожено, ничто не должно измениться в представлении предка. Если представление предка будет уничтожено, Backbone автоматически отделит обработчики.

Предостережение: я еще не пробовал это, так что там где-то может быть gotcha.

Ответ 3

Вы должны проверить плагин Backbone.Courier, поскольку события барботирования являются идеальным вариантом:

https://github.com/dgbeck/backbone.courier

Ответ 4

Итак, я придумал решение - создаю объект, который расширяет Backbone.Events, и передавайте его как параметр для нескольких видов. Это почти похоже на передачу сообщений между актерами или чем-то еще. В любом случае - я отправляю это как ответ, если кому-то еще нужно быстрое решение, но я не собираюсь принимать ответ. Это чувствует себя взломанным. Я все еще хотел бы найти лучшее решение.

NewsListView = Backbone.View.extend({
    el: $('li#newspane'),

    // Too bad this doesn't work, it'd be really convenient
    // events: { 'filtered': 'reset' }

    initialize: function() {
        _.bindAll(this);
        // but at least this does
        this.options.eventProxy.bind('filtered', this.reset);
    },
    render: function() {},
    reset: function() {}
});

FilterView = Backbone.View.extend({
    el: $('li.filter'),

    initialize: function() {},
    render: function() {},
    toggleFilter: function() {
        this.options.eventProxy.trigger('filtered');
    }
});

AllView = Backbone.View.extend({
    initialize: function() {
        var eventProxy = {};
        _.extend(eventProxy, Backbone.Events);
        this.newsListView = new NewsListView({eventProxy: eventProxy});
        this.filterView = new FilterView({eventProxy: eventProxy});
    }
});

Ответ 5

Эта проблема может быть решена с помощью небольшого backbone.js hack. Просто измените Backbone.Events.trigger для передачи событий в this.parent

if this.parent != null

Ответ 6

Самый простой способ, который я нашел для запуска и прослушивания событий, - это просто использовать сам объект Backbone. У него уже есть функции, смешанные с ним, поэтому вы можете просто вызвать, например:

Backbone.trigger('view:eventname',{extra_thing:whatever, thing2:whatever2});

то в любом другом режиме в вашем приложении вы можете прослушивать это событие, например:

Backbone.on('view:eventname', function(passed_obj) {
    console.log(passed_obj.extra_thing);
});

Я не совсем уверен, что преимущество в том, что вы не используете объект Backbone в качестве обработчика событий, а вместо этого создаете отдельный объект для этого, но для быстрой и грязной работы это работает отлично. НТН!

ПРИМЕЧАНИЕ. Одним из недостатков этого является то, что каждый слушатель будет "слышать" каждое событие, инициированное таким образом. Не уверен, что такое большой O, но старайтесь не перегружать свои взгляды большим количеством этого материала. Опять же: это быстро и грязно!:)