1

Я столкнулся с этой статьей (http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/) и задавался вопросом, является ли идея привязки и визуализации представлений в маршрутизаторе после их создания наилучшей практикой. Я привязывал свои взгляды и делал их в своем определении.Backbonejs view binding conceptual feedback

В настоящее время это, как я создание и вызов моих взглядов:

EmployeeView:

EmployeeView = Backbone.View.extend({ 
    el: '#content', 
    template:template, 

    initialize: function() { 

    this.collection.fetch({ 
     reset: true 
    }); 

    this.collection.on('reset',this.render, this); 
    }, 
    render: function(){ 
    this.el.innerHTML = Mustache.to_html(this.template, { employee_list: this.collection.toJSON()}); 
    console.log('render called');  
    } 

Мой маршрутизатор:

employeeList: function() { 
    var c = new EmployeeCollection 
    new EmployeeView({ 
     collection: c 
    }); 
    } 

Он отлично работает. Но согласно статье лучше практике сделать следующее:

EmployeeView = Backbone.View.extend({ 

    template:template, 

    initialize: function() { 

    this.collection.fetch({ 
     reset: true 
    }); 

    this.collection.on('reset',this.render, this); 
    }, 
    render: function(){ 
    this.el.innerHTML = Mustache.to_html(this.template, { employee_list: this.collection.toJSON()}); 
    console.log('render called'); 
    return this; 
    } 

маршрутизатора

employeeList: function() { 
    var c = new EmployeeCollection 
    $('#content').html(new EmployeeView({collection: c}).render().el); 
    }, 

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

  1. Действительно ли это самая лучшая практика?
  2. Как избежать вызова рендера дважды, если я хочу использовать предложенный метод?
  3. Что делать, если у меня есть случаи, когда у меня есть взаимодействие с конечным пользователем, а затем нужно обновить коллекцию/модель представления? Должен ли я сделать это с моей точки зрения или это может случиться и в маршрутизаторе?

ответ

1

Вид, который вы здесь, и тот, который в этой статье совершенно другой.

В вашем примере, вид привязан к элементу в DOM (#content)
, которая не является хорошей практикой, особенно для начинающих и вызывает много ошибок, которые мы видим здесь каждый день.

Например, если вы создаете 2 экземпляра своего вида, тогда событие начнет стрелять кратным раз и вместе с тем, что все ад сломается.


мнение в статье создает новый <div> элемент памяти на экземпляр, который является хорошей практикой.

Теперь, чтобы добавить это в DOM, новички часто такие вещи, как следующий внутри вид визуализирует:

$('#content').html(this.$el); 

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

В статье, возможно (я ее не читал), речь идет о проблеме и представляет и альтернативу добавления элемента представления к DOM с маршрутизатора, что является хорошей практикой, на мой взгляд.


Чтобы избежать рендеринга дважды в коде из статьи вы можете просто сделать:

$('#content').html(new EmployeeView({collection: c}).el); 

el быть живой ссылки, он будет обновляться, когда выборка успешно. .render().el - это еще одно распространенное недопонимание, распространяемое всеми существующими блогами и учебниками.


Side Примечание: Поскольку мы обсуждаем лучшие практики, опуская точку с запятой и скобки, как в var c = new EmployeeCollection не является хорошей практикой либо. Идут с var c = new EmployeeCollection();

1

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

EmployeeView = Backbone.View.extend({ 
    template:template, 

    initialize: function(){ 
    console.log("Will print second"); 
    this.collection.fetch({ reset: true }); 
    this.collection.on('reset', this.appendEmployees, this); 
    }, 
    render: function(){ 
    //this.el.innerHTML = Mustache.to_html(this.template, { employee_list: this.collection.toJSON()}); 
    console.log('Will print 3rd. render called'); 
    return this; 
    } 

    appendEmployees: function(){ 
    console.log("Will print 4th. Appending employees"); 
    $(this.el).html(Mustache.to_html(this.template, {employee_list: this.collection.toJSON() }); 
    } 

}) 

маршрутизатор

employeeList: function() { 
    var c = new EmployeeCollection() 
    var view = new EmployeeView({ collection: c }); 
    console.log("Will print 1st"); 
    $('#content').html(view.render().el); 
} 

Во-первых, когда вы делаете view.render().el это добавит элемент вида по (который будет пустым к тому времени), чтобы #content

Во-вторых, вы выполнения appendEmployees функцию, когда сбор сбрасывается. К тому времени, когда это произойдет, ваш элемент уже будет помещен в DOM.

Если вам необходимо обновить, это можно сделать внутри представления, вызвав функцию appendEmployees или даже сбросив вашу коллекцию. Или, если вы перейдете к одному и тому же маршруту через магистраль, весь процесс будет повторяться, поэтому ваша коллекция будет вызвана снова, а страница будет отображаться с начала. Таким образом, все зависит от ваших предпочтений от того, когда/почему вы выбираете один из них. Надеюсь это поможет.