2016-12-11 10 views
-1

Я пытаюсь создать некоторые комбинированные поля, чтобы их данные извлекались с сервера. Все они одинаковые, но данные разные. Это функция моего MainView визуализации:Магистральный вид расширяется?

render: function() { 

     ... 

     this.$el.append(this.template(this.options)); 


     this.$('#Type').append(new App.Views.TicketTypes({ collection : new App.Models.TicketTypes() }).render().el); 

     this.$('#Priority').append(new App.Views.Priorities({ collection : new App.Models.Priorities() }).render().el); 

     this.$('#Status').append(new App.Views.Statuses({ collection : new App.Models.Statuses() }).render().el); 

     this.$('#State').append(new App.Views.States({ collection : new App.Models.States() }).render().el); 


     return this; 
    } 

это Основной шаблон:

<label class="text-center">{{Type}}</label> 
        <br> 
        <div id="Type" class="form-group"> 

        </div> 
        <label class="text-center">{{Priority}}</label> 
        <br> 
        <div id="Priority"> 

        </div> 
        <label class="text-center">{{Status}}</label> 
        <br> 
        <div id="Status"> 

        </div> 
        <label class="text-center">{{State}}</label> 
        <br> 
        <div id="State"> 

        </div> 
        <br> 

И это мои мнения, что я определил:

App.Views.SelectList = Backbone.View.extend({ 
    template: templates.SelectList, 
    collection : null, 
    initialize: function (options) { 
     if (options) { 
      this.collection = options.collection; 
     } 
    }, 
    render: function() { 
     this.el.innerHTML = this.template(this.options); 
     thiz = this; 
     this.collection.fetch({beforeSend :App.Auth , success : function (collection , response) { 
      collection.each(function (item) { 
       thiz.$('select').append("<option>" + item.get('Text') + "</option>"); 
        } , this); 
     }}); 

     return this; 
    } 
}); 

App.Views.TicketTypes = App.Views.SelectList.extend(); 
App.Views.Priorities = App.Views.SelectList.extend(); 
App.Views.Statuses = App.Views.SelectList.extend(); 
App.Views.States = App.Views.SelectList.extend(); 

Это SelectList Шаблон:

<select class="form-control"> 

</select> 
<br> 

Все мои Модели, как это:

{"id":1,"Text":"Netowrk"} 

Но это то, что я получаю от сервера: enter image description here

Как вы можете видеть только последний Гоц данные и удивительно все данные всех моделей попали в последний. смотрите здесь:

enter image description here

Я знаю, если я изменить это вынести функцию:

render: function() { 
      this.el.innerHTML = this.template(this.options); 
      thiz = this; 
      this.collection.fetch({beforeSend :App.Auth , success : function (collection , response) { 
       collection.each(function (item) { 
        thiz.$('select').append("<option>" + item.get('Text') + "</option>"); 
         } , this); 
      }}); 

      return this; 
     } 

к этому:

render: function() { 
     this.el.innerHTML = this.template(this.options); 
     this.collection.thiz = this; 
     this.collection.fetch({beforeSend :App.Auth , success : function (collection , response) { 
      collection.each(function (item) { 
       collection.thiz.$('select').append("<option>" + item.get('Text') + "</option>"); 
        } , this); 
     }}); 

     return this; 
    } 

Это будет решить эту проблему, но есть ли лучший способ сделать это?

Спасибо.

ответ

2

У вас есть проблема с определением области. Это:

thiz = this; 

создает глобальную переменную thiz поэтому каждый анонимную функцию в итерации по коллекции:

collection.each(function (item) { 
    thiz.$('select').append("<option>" + item.get('Text') + "</option>"); 
} , this); 

заканчивает с использованием точно такой же thiz. Те вызовы collection.each обернуты внутри вызова AJAX (this.collection.fetch), и JavaScript однопоточный, поэтому все они будут созданы до того, как будет выполнен первый. Это означает, что все эти функции будут использовать точно то же самое thiz, и его значение будет зависеть от последнего назначенного ему thiz = this. Это классическая проблема закрытия в маскировке.

При переключении на:

this.collection.thiz = this; 

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

Надлежащее решение было бы правильно объявить thiz с помощью var или let:

var thiz = this; 
// or 
let thiz = this; 

Проверьте связанный документации разницу.

 Смежные вопросы

  • Нет связанных вопросов^_^