2014-11-18 2 views
1

Этот вопрос следует из другого вопроса, который я задал, но парень, который, я думаю, пытался объяснить что-то еще, или, скорее всего, я не объяснил свое право.Подчеркивание шаблона, без петли?

Итак, весь мой базовый код работает и отображает данные с выходными данными. Теперь для этого объясните мои тестовые данные, у меня есть 17 строк входов, но даже без создания цикла _.each, его цикл примерно 17 раз, что я просто не понимаю, почему?

Так мой Backbone код,

var TimeSheetModel = Backbone.Model.extend({ 
    defaults: { 
     Timesheetrow: "", 

    } 
}); //End of Timesheet Model 

var TimeSheetCollection = Backbone.Collection.extend({ 
    model: TimeSheetModel, 
    url: '/dashboard/jsondata/' + TimesheetID() 
}); //End of Timesheet Collection 

var TimeSheetView = Backbone.View.extend({ 
    el:'#testarea', //HTML loading area for the data 

    template: _.template($('#TimesheetData').html()), //Template to load the JSON data into 

    initialize: function(){ 
     var NewTimeSheetCollection = new TimeSheetCollection(); //New Instance Of Collecttion 
     this.listenTo(NewTimeSheetCollection, "add", this.AddMyModel); 
     NewTimeSheetCollection.fetch(); 
    }, 

    AddMyModel: function(TimeSheetModel) { //apply model data to view template and append to view element 
     this.$el.append(this.template(TimeSheetModel.toJSON())); 
     //$(this.el).html(this.template(TimeSheetRowModel.toJSON())); 
    } 
}); //End of Timesheet View 

//New Instance & render call for the set Timesheet View. 
NewTimeSheetVew = new TimeSheetView(); 
//NewTimeSheetVew.render(); <- do I need this? seems to work, without it? 

}); 

И мой код шаблона Подчеркивание

<script type="text/template" id="TimesheetData"> 

<% console.log(Timesheetrow) %> 

<% _(1).times(function(n){ n=2; }); //just a test bit of code %> 


<% if(Timesheetrow.jobtitle) { %> 

    <form action="#" method="post" id="TimesheetDataList"> 

     <div class="TimesheetRowData"> 
      <input type="hidden" name="data[Timesheetrow][0][id]" value="<%= Timesheetrow.id %>"> 
      <input type="type" name="data[Timesheetrow][0][jobtitle]" value="<%= Timesheetrow.jobtitle %>"> 
     </div> 

    </form> 

<% }; %> 

</script> 

так что моя цель состоит в том, чтобы использовать позвоночник, чтобы иметь один основной вид, и петлю вокруг 17 раз (или X, в зависимости от заданных пользователем строк). Так, например, я бы выход, как:

<form id="ID-HERE"> 
     <div><input value="XXXXX"></div> 
     <div><input value="XXXXX"></div> 
     <div><input value="XXXXX"></div> 
     <div><input value="XXXXX"></div> 
     <div><input value="XXXXX"></div> 
</form> 

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

Любая помощь приветствуется.

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

Спасибо,

ответ

2

Вы слушаете событие добавления в коллекции, которая будет уволена после выборки операции для каждой модели извлеченной с сервера:

this.listenTo(NewTimeSheetCollection, "add", this.AddMyModel); 
NewTimeSheetCollection.fetch(); 

Так что ваш сервер возвращает 17 строки, событие добавления запускается 17 раз, и каждый раз, когда ваша функция AddMyModel выполняет рендеринг шаблона. (Если вы посмотрите на documentation, выборка использует внутри метод set, который будет запускать события добавления).

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

У вас есть несколько способов исправить эту проблему, в основном расщепление, что должно быть вынесено сразу и то, что должно быть вынесено для каждой модели:

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

  • Разделите свой шаблон в 2: главный с контуром формы и дочерний с входами для одного TimesheetRow. Отметьте исходный шаблон для инициализации вида и продолжайте слушать события добавления коллекции. На странице AddMyModel отрисуйте дочерний шаблон и добавьте его в форму.

  • Разделите свой вид на главный вид и вид ребенка. Мастер-представление отобразит форму и извлечет коллекцию, прослушивая добавления событий. Для каждой добавленной модели он создаст новый экземпляр дочернего представления, передающий ему добавленную модель, рендеринга и добавление ее el внутри формы.


EDIT

Я создал jsfiddle с третьим вариантом. Есть 2 просмотров TimeSheetRowView и TimeSheetCollectionView:

var TimeSheetRowView = Backbone.View.extend({ 
    className:'TimesheetRowData', 
    template: _.template($('#TimesheetData').html()), 
    render: function() { 
     this.$el.append(this.template(this.model.toJSON())); 
     return this.$el; 
    } 
}); 

var TimeSheetCollectionView = Backbone.View.extend({ 
    el:'#MasterContainer', 
    template: _.template($('#TimesheetForm').html()), 
    initialize: function(){ 
     //render master template 
     this.$el.append(this.template()); 
     //keep element so we insert child views before it, inside the form 
     this.submitButton = this.$(".actionSubmit"); 
     //initialize collection and listen to events 
     this.collection = new TimeSheetCollection(); 
     this.listenTo(this.collection, "add", this.AddTimesheetRow); 

     //simulate a fetch just setting the models 
     var hardcodedModels = [{Timesheetrow: {id: 1, index: 0, jobtitle: 'Foo'}}, 
           {Timesheetrow: {id: 2, index: 1, jobtitle: 'Bar'}}]; 
     this.collection.set(hardcodedModels); 
    }, 
    AddTimesheetRow: function(model) { 
     //render a single row view and insert it inside the form, right before the submit button 
     var view = new TimeSheetRowView({model: model}); 
     //view.render() returns its $el so we can chain the insertBefore method 
     view.render().insertBefore(this.submitButton); 
    } 
}); 

И шаблоны были разделены, как:

<script type="text/template" id="TimesheetForm"> 
    <form action="#" method="post" id="TimesheetDataList"> 
     <input type="submit" class="actionSubmit" value="Send"/> 
    </form> 
</script> 

<script type="text/template" id="TimesheetData">  
    <input type="hidden" name="data[Timesheetrow][<%= Timesheetrow.index %>][id]" value="<%= Timesheetrow.id %>"> 
    <input type="type" name="data[Timesheetrow][<%= Timesheetrow.index %>][jobtitle]" value="<%= Timesheetrow.jobtitle %>">   
</script> 
+0

@ DANIEL-J-г, Большое спасибо, очень хороший ответ. Дает мне очень четкую направленность на то, что нужно исследовать. Какой метод, по вашему выбору, является лучшим? Или это просто сводится к тому, как вы хотите его закодировать? Первый вариант выглядит лучше всего, поскольку он получает основу, чтобы делать больше работы и делает шаблон более простым. –

+0

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

+0

@ daniel-j-g. Были ли у вас хорошие сайты для примеров на представлениях мастера/ребенка? Я перешел к документам Underscore & Backbone, но мне их немного сложно следовать, поскольку они только дают небольшой пример кода, а не целый рабочий раздел кода, который я считаю лучше всего понятым, но это может быть просто мне :) –

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