Можно ли добавить подпункты к сетке в backbone.js? - PullRequest
1 голос
/ 23 марта 2012

Я загружаю данные JSON (массив объектов) через сервис onReady и хочу отобразить эти данные в сетке. У меня каждая строка представлена ​​представлением.

        render: function(){
            var self = this;
            (self.collection.models).forEach( function(model){
                var rowView = new RowView({model: model});
                self.$el.append(rowView.render().el);
            });                
        }

Можно ли создать подпредставления и сразу отправить их в DOM вместо перехода 1 на 1? Происходит ли перекомпоновка и перерисовка браузера при каждом добавлении?

Я видел все способы, которыми люди добавляют подпредставления / детей, но ни один из них не решает проблему (частый доступ к DOM?), Потому что именно так строится магистраль?

Ответы [ 2 ]

3 голосов
/ 23 марта 2012

Да, это можно сделать.Сгенерируйте html-элемент с помощью jQuery (используя определение tagName представления и attributes и все такое), а затем добавьте все к этому.Когда вы закончите, замените текущий this.$el на новый:

render: function(){

  // create in memory element
  var $el = $(this.tagName);
  // also get the `className`, `id`, `attributes` if you need them

  // append everything to the in-memory element
  this.collection.each(function(model){
    var rowView = new RowView({model: model});
    $el.append(rowView.render().el);
  });

  // replace the old view element with the new one, in the DOM
  this.$el.replaceWith($el);

  // reset the view instance to work with the new $el
  this.setElement($el);
}

Это должно сделать это.

Конечно, вы увидите немногомерцание на экране, в зависимости от того, насколько быстро работает браузер и насколько велико изменение.Но это должно помочь вам сделать то, что вы хотите.

Подробнее о replaceWith: http://api.jquery.com/replaceWith/

2 голосов
/ 26 апреля 2012

Я думаю, что есть более простое решение, чем ответ @ Derick:

render : function () {

  var children = [];

  this.collection.forEach( function( model ) {

    var rowView = new RowView( { model : model } );

    children.push( rowView.render().el );

  } );


  this.$el.empty().append( children );


  return this;

}

http://jsfiddle.net/tXnTk/

Комментарии к коду в ответе @ Derick (мои комментарии отмечены как «[JMM]:»):

render: function(){

  // [JMM]: You should already have this.el / this.$el, so there 
  // [JMM]: should be no need to mess with this.tagName, className, 
  // [JMM]: id, etc. Just store the child views in an array.

  // create in memory element
  var $el = $(this.tagName);
  // also get the `className`, `id`, `attributes` if you need them

  // append everything to the in-memory element
  this.collection.each(function(model){
    var rowView = new RowView({model: model});
    $el.append(rowView.render().el);
  });


  // [JMM]: Using replaceWith will wipe out event listener
  // [JMM]: registrations and other data associated with the
  // [JMM]: DOM element. That's why it's necessary to call
  // [JMM]: setElement() afterward. Since you already have
  // [JMM]: the DOM element and you just want to change the
  // [JMM]: content you might as well just empty it out and
  // [JMM]: append the new children.

  // replace the old view element with the new one, in the DOM
  this.$el.replaceWith($el);

  // reset the view instance to work with the new $el
  this.setElement($el);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...