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

Я новичок в backbone.js и пытаюсь понять, как работают маршруты, представления и т. д., и теперь у меня проблема с созданием событий для одного и того же представления. вот клип, который покажет вам именно то, что я имею в виду. http://screencast.com/t/QIGNpeT2OUWu

Так выглядит мой магистральный маршрутизатор

var Router = Backbone.Router.extend({

    routes: {
        "pages": "pages",
    }
    pages: function () {
        var page_view = new PageView();
    }
});

Поэтому, когда я нажимаю ссылку Pages, я создаю новый PageView, и это код, который я использую

PageView = Backbone.View.extend({
    el: $("#content"),
    initialize: function () {
        $.ajax({
            url: '/pages',
            success: function (data) {
                $("#content").html(data);
            }
        });
    },
    events: {
        "click td input[type=checkbox]": "updatePublishedStatus"
    },
    updatePublishedStatus: function (event) {
        console.log('update publish status');
    }
});

довольно просто, я думаю, но, как вы можете видеть в клипе, каждый раз, когда я перехожу к /pages, я получаю другое событие, зарегистрированное для флажка.


person marcus    schedule 20.02.2012    source источник


Ответы (2)


Здесь что-то идет не так.

  1. В вашем видео хорошо видно, что страницы являются коллекцией, Pages. Pages быть Backbone.Model с такими атрибутами, как имя страницы, ярлык, опубликовано и т. д. Вам этого не хватает, и это будет больно. Вы не должны просто загружать какой-то html и помещать его в свою DOM, это в первую очередь бросает вызов самой цели использования Backbone.
  2. Если вы создадите модель для страницы, у нее будет представление. Тогда ваш маршрут /pages покажет вид страниц коллекции и т. д.
  3. Вы получите свои данные не внутри инициализации представления, а скорее, выполнив pages.fetch();, где страницы являются экземпляром коллекции Pages. Это может произойти еще до того, как вы инициализируете маршрутизатор.
  4. При изменении атрибутов в вашем представлении отдельные модели будут обновляться.

В качестве побочного эффекта: выборка данных при инициализации не очень хороша. Вы можете вызвать render() до того, как получите данные, и это неинтересно. Также вместо $('#content') вы можете использовать представление $el. Как в this.$el.html(...);

person ggozad    schedule 20.02.2012
comment
Хорошо, я понимаю, что следует использовать Модели и Коллекции. Я использую asp.net mvc, и когда вызывается /pages, я просто возвращаю частичное представление со всеми html и данными, потому что я не понял, как заставить его работать с включенным javascript или без него, если я не использую частичное представление . Есть ли у вас опыт создания многофункционального веб-приложения с asp.net mvc, которое также ненавязчиво и работает без включенного javascript? - person marcus; 21.02.2012
comment
Ни один человек, извините, я не знаю, я люблю свой питон ;) Но если ваша цель состоит в том, чтобы сделать приложение, которое не зависит от наличия javascript и игнорирует идею наличия моделей для ваших представлений Backbone, вам, вероятно, следует пересмотреть использование Backbone в первое место. - person ggozad; 21.02.2012
comment
Хорошо, я вижу :) ... Я думаю, что придумаю решение, и я согласен с вами, что я должен использовать модели и коллекции. - person marcus; 21.02.2012
comment
Так ли плохо рендерить до того, как данные будут получены? Если представление отображается пустым, а затем повторно отображается или обновляется при запуске события «сброс», это не так уж плохо. - person Paul Hoenecke; 21.02.2012
comment
@PaulHoenecke нет, это второстепенно, но, по крайней мере, для сброса требуется привязка. - person ggozad; 21.02.2012

Переместите var page_view = new PageView() за пределы Router.pages().

Попросите обратный вызов PageView.initialize() сохранить data в переменной. Либо в PageView, либо в модели.

Добавьте функцию render к PageView, которая устанавливает $("#content").html(data);.

Позвоните page_view.render() в пределах Router.pages().

person abraham    schedule 20.02.2012
comment
В этом случае рендеринг может быть вызван до получения данных. - person ggozad; 21.02.2012