Backbone.View "el" путаница


97

Как следует elобрабатывать представление? Его нужно установить, иначе события не сработают (см. Здесь ).

Но должен ли это быть элемент, который уже есть на странице? В своем приложении я визуализирую шаблон (jQuery Templates) в Fancybox. Что должно elбыть в таком случае?


11
Я подумал - я единственный, кто теребит эту elштуку.
Yugal Jindle

elнравится gf. никто не может понять их полностью.
Махи

Ответы:


121

Эль представлений - это место, где происходит привязка всех событий. Вам не обязательно использовать его, но если вы хотите, чтобы магистраль запускала события, вам необходимо выполнить рендеринг на el. Представления el - это элемент DOM, но он не обязательно должен быть ранее существовавшим элементом. Он будет создан, если вы не извлечете его со своей текущей страницы, но вам придется вставить его на страницу, если вы когда-нибудь захотите увидеть, как он что-то делает.

Пример: у меня есть представление, которое создает отдельные элементы

window.ItemView = Backbone.View.extend({
    tagName: "li", //this defaults to div if you don't declare it.
    template: _.template("<p><%= someModelKey %></p>"),
    events: {
         //this event will be attached to the model elements in
         //the el of every view inserted by AppView below
        "click": "someFunctionThatDoesSomething"
    },
    initialize: function () { 
        _.bindAll(this, "render");
        this.render();
    },
    render: function () {
        this.el.innerHTML = this.template(this.model.toJSON());
        return this;
    }
});
window.AppView = Backbone.View.extend({
    el: $("#someElementID"), //Here we actually grab a pre-existing element
    initialize: function () { 
        _.bindAll(this, "render");
        this.render(new myModel());
    },
    render: function (item) { 
        var view = new ItemView({ model: item });
        this.el.append(view.render().el);
    }
});

Первое представление просто создает элементы списка, а второе представление фактически размещает их на странице. Я думаю, это очень похоже на то, что происходит в примере ToDo на сайте backbone.js. Я думаю, что конвенция заключается в том, чтобы передать вам содержимое в el. Таким образом, el служит местом посадки или контейнером для размещения вашего шаблонного контента. Затем Backbone связывает свои события с данными модели внутри него.

При создании представления можно манипулировать эл четырьмя способами , используя el:, tagName:, className:и id:. Если ничего из этого не объявлено, по умолчанию используется div без идентификатора или класса. На данный момент он также не связан со страницей. Вы можете изменить тег на что-нибудь другое, используя tagName (например tagName: "li", даст вам el of <li></li>). Вы также можете установить идентификатор и класс el. Тем не менее el не является частью вашей страницы. Свойство el позволяет выполнять очень тонкую обработку объекта el. В большинстве случаев я используюel: $("someElementInThePage")который фактически связывает все манипуляции, которые вы делаете в вашем представлении, с текущей страницей. В противном случае, если вы хотите, чтобы вся тяжелая работа, которую вы проделали в своем представлении, отображалась на странице, вам нужно будет вставить / добавить ее на страницу в другом месте в вашем представлении (возможно, при визуализации). Мне нравится думать об el как о контейнере, которым манипулирует все ваше представление.


Спасибо за пояснение и пример! Я думаю, не всегда ясно, каким должен быть el в определенных ситуациях, и разработчик должен это «почувствовать». Ваши объяснения, безусловно, помогли! Однако один вопрос: вы не определяете el в своем ItemView, но получаете к нему доступ в функции рендеринга. Это сработает? Есть ли какой-то тип el по умолчанию, если вы не определяете его явно?
Мануэль Мёрер

3
По умолчанию el - это тег «div» без идентификатора или класса. Это объект DOM, не привязанный к DOM вашей страницы. Обычно я вставляю / добавляю его на страницу в функции рендеринга или функции рендеринга родительского представления.
LeRoy

Обновил мой ответ с некоторым описанием свойств, которые определяют эл.
LeRoy

5
Я думаю, моя единственная проблема с захватом уже существующего элемента с помощью el: $ ("# someElementID") - ваше представление, вероятно, знает больше, чем должно, что затрудняет его повторное использование. см. «Отделить представление от DOM ...» coenraets.org/blog/2012/01/…
Скотт Коутс

@scoarescoare, поскольку вы добавляете свойство el при создании экземпляра, само представление на самом деле не знает больше, чем должно, оно остается модульным и может принимать любые $ (el), которые вы хотите передать. Так что это делает его действительно многоразовым.
Metagrapher

6

Немного устарел, но я тоже был смущен, поэтому другим людям, которые сюда попадают, эта скрипка может помочь - http://jsfiddle.net/hRndn/2/

var MyView = Backbone.View.extend({

    events: {
        "click .btn" : "sayHello",
    },

    sayHello : function() {
        alert("Hello");
    },


    render : function() {
        this.$el.html("<input type='button' class='btn' value='Say Hello'></input>");

    }
});

$(function() {
    myView = new MyView({el:"#parent_id"});
    myView.render();
});

Я следовал этой модели и очень хотел бы этого не делать. Чтобы уничтожить представление и удалить привязки, используется базовое соглашение view.remove (). Это разрушает $ el и удаляет его из DOM, поэтому, когда вам нужно снова показать представление, $ el не существует.
JJ

@ Отметьте, что, если я использую композитную архитектуру, например марионетку .... мне все еще нужно иметь представление el?
afr0 07

ваш код скрипки не работает, так как ссылка должна быть jsfiddle.net/hRndn
Иззи,

@ Махи Да, ты прав. Возможно, я вставил не ту ссылку, извините. Этот работает: jsfiddle.net/hRndn/127
Иззи,

1

Вы хотите, чтобы ваш 'el' ссылался на элемент, содержащий дочерний элемент, у которого есть какое-либо событие, которое вызывает изменение в вашем представлении. Может быть размером с тег "body".


Хм, это тоже не совсем проясняет. В большинстве случаев элементы, которые могут вызвать изменение в моем представлении, находятся внутри шаблона, который визуализируется представлением, поэтому до его визуализации эти элементы еще не существуют.
Мануэль Мёрер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.