Использование Event Aggregator для загрузки представления с другой моделью в магистрали js
Я новичок в backbone.js начал с позвоночника неделю назад. Я должен был сделать демо. Основная идея заключается в том, что когда страница загружена, мне нужно показать курсы, и по умолчанию список студентов для первого курса в списке. Вот код для отображения списка курсов, который находится вcourse.js файл
//Model
var Course = Backbone.Model.extend({
urlRoot: '/api/courses/',
idAttribute: 'Id',
defaults:{
Id: null,
Name: ""
},
validate: function (attr) {
if (!attr.Name)
return "Name is required";
}
});
var Courses = Backbone.Collection.extend({
model: Course,
url: '/api/courses'
});
//Views
var CourseList = Backbone.View.extend({
tagName: 'ul',
initialize: function () {
this.collection.on('reset', this.renderAll, this);
this.collection.on('add', this.render, this);
this.collection.fetch();
_.bindAll(this, 'renderAll', 'render');
return this;
},
renderAll: function () {
this.collection.each(this.render);
$('#spnStdntCourseName').text('Students Enrolled in ' + this.collection.at(0).get("Name"));
},
render: function (model) {
var item = new CourseItem({ model: model });
this.$el.append(item.el);
},
events: {
"click #btnAddCourse": "createNewCourse",
"keypress #txtNewCourse": "createOnEnter"
},
createOnEnter: function (e) {
if (e.keyCode == 13) {
this.createNewCourse();
}
},
createNewCourse: function () {
this.collection.create({ Name: this.$el.find('#txtNewCourse').val() });
this.$el.find('#txtNewCourse').val('');
}
});
var CourseItem = Backbone.View.extend({
tagName: 'li',
className: 'courseli',
events: {
'click .remove': 'deleteItem',
'click .edit': 'showEdit',
'click': 'courseClicked'
},
initialize: function () {
this.template = _.template($('#course').html()),
this.model.on('change', this.render, this);
this.render();
},
render: function () {
var html = this.template(this.model.toJSON());
this.$el.html('').html(html);
},
courseClicked: function () {
$('#spnStdntCourseName').text('Students Enrolled in ' + this.model.get("Name"));
Vent.trigger('studentDetails',"how to load student list from here based on courseID...?");
},
showEdit: function (event) {
event.preventDefault();
Vent.trigger('edit', this.model);
},
deleteItem: function () {
this.model.destroy();
this.remove();
}
});
var CourseEdit = Backbone.View.extend({
el: '#courseEdit',
events: {
'click #save': 'save',
'click #cancel': 'cancel'
},
initialize: function () {
_.bindAll(this, 'render', 'save');
Vent.on('edit', this.render);
this.template = _.template($('#courseEditTemplate').html())
},
render: function (model) {
var data, html;
this.model = model;
data = this.model.toJSON();
html = this.template(data);
this.$el.html(html)
.show()
.find('#name')
.focus();
this.model.on('error', this.showErrors, this);
},
save: function (event) {
var self = this;
this.model.save({
'Name': this.$el.find('#name').val()
}, {
success: function () {
alert('Saved!');
if (!window.courses.any(function (course) {
return course.get('Id') === self.model.get('Id');
})) {
window.courses.add(self.model);
}
self.$el.hide();
}
});
},
cancel: function () {
this.$el.hide();
},
showErrors: function (model, error) {
var errors = '';
if (typeof error === 'object') {
errors = JSON.parse(error.responseText).join('<br/>');
alert(errors);
}
else {
alert(error);
}
}
});
var Vent = _.extend({ }, Backbone.Events);
window.courses = new Courses();
$(function () {
var edit = new CourseEdit(),
list = new CourseList({
collection: window.courses,
el: '#coursesList'
});
});
Пожалуйста, посмотрите на'courseClicked' функция внутриCourseItem Представление: предполагается, что список студентов загружается при нажатии на элемент курса.
Теперь у меня есть мойStudent модель и представления в Students.js, как показано ниже
var Student = Backbone.Model.extend({
urlRoot: '/api/students/',
idAttribute: 'Id',
defaults: {
Id: null
},
validate: function (attr) {
if (!attr.Name)
return "Name is required";
}
});
var Students = Backbone.Collection.extend({
model: Student,
url: '/api/students'
});
//Views
var StudentList = Backbone.View.extend({
tagName: 'ul',
initialize: function () {
this.collection.on('reset', this.renderAll, this);
this.collection.on('add', this.render, this);
this.collection.fetch({ data: $.param({ courseId: 11 }) });
_.bindAll(this, 'renderAll', 'render');
return this;
Vent.on('studentDetails', this.render);
},
renderAll: function () {
this.collection.each(this.render);
},
render: function (model) {
var item = new StudentItem({ model: model });
this.$el.append(item.el);
},
events: {
"click #btnAddStudent": "createNewStudent",
"keypress #txtNewStudent": "createOnEnter"
},
createOnEnter: function (e) {
if (e.keyCode == 13) {
this.createNewStudent();
}
},
createNewStudent: function () {
this.collection.create({ Name: this.$el.find('#txtNewStudent').val() });
this.$el.find('#txtNewStudent').val('');
}
});
var StudentItem = Backbone.View.extend({
tagName: 'li',
className: 'studentli',
events: {
'click .remove': 'deleteItem',
'click': 'studentClicked'
},
initialize: function () {
this.template = _.template($('#student').html()),
this.model.on('change', this.render, this);
this.render();
},
render: function () {
var html = this.template(this.model.toJSON());
this.$el.html('').html(html);
},
studentClicked: function () {
var Id = this.model.get("Id");
},
deleteItem: function () {
this.model.destroy();
this.remove();
}
});
window.students = new Students();
$(function () {
var studentDetails = new StudentList({
collection: window.students,
el: '#studentsList'
});
});
так внутри документа. уже у меня естьstudentDetails переменная, которая загружает список студентов. Вот моя проблема, поскольку на данный момент я загрузил список студентов при загрузке страницы, передав некоторый параметр жесткого кода в fetch, как показано ниже
this.collection.fetch({ data: $.param({ courseId: 11 }) });
но что мне нужно показать, так это список студентов для первого курса в представлении курсоров при загрузке страницы, а на более поздних этапах - список студентов для каждого элемента курса. Для этой цели, если вы можете вспомнить в & Quot; courseClicked & Quot; функция внутри & quot; CourseItem & quot; посмотреть в course.js, я использовал
Vent.trigger('studentDetails',"how to load student list from here based on courseID...?");
studentDetails - это переменная, которую я инициализировал в student.js (в приведенном выше коде) следующим образом
window.students = new Students();
$(function () {
var studentDetails = new StudentList({
collection: window.students,
el: '#studentsList'
});
});
Поэтому, когда я запускаю studentDetails, мне определенно нужна модель студента внутри моей функции courseClicked, которая недоступна в этом контексте. Я полагаю, вы, ребята, поняли мою проблему из приведенного выше объяснения. Так как мне это исправить ...? Это неправильный подход? ..? Любая хорошая альтернатива, нужны предложения. Надеюсь, что в этом вопросе не слишком много шума.
EDIT
var CourseList = Backbone.View.extend({
tagName: 'ul',
initialize: function () {
this.students = new Students();
var studentList = new StudentList({
collection: this.students,
el: '#studentsList'
});
this.collection.on('reset', this.renderAll, this);
this.collection.on('add', this.render, this);
this.collection.fetch();
_.bindAll(this, 'renderAll', 'render');
return this;
},
renderAll: function () {
this.collection.each(this.render);
$('#spnStdntCourseName').text('Students Enrolled in ' + this.collection.at(0).get("Name"));
this.students.fetch({ data: $.param({ courseId: this.collection.at(0).get("Id") }) });
},
render: function (model) {
this.$el.html("");
var item = new CourseItem({ model: model, students: this.students});
this.$el.append(item.el);
}
})
Я сделал следующие изменения
1.students в коллекции this.students (внутри инициализации представления «CourseList») в приведенном ниже коде
initialize: function () {
this.students = new Students();
var studentList = new StudentList({
collection: this.students,
el: '#studentsList'
});
2. Я выбрал студентов из функции renderAll вместо функции render, потому что для каждого элемента курса, который был выбран, студент также выбирается. Я имею в виду, что если есть 6 курсов, я получаю возможность увидеть студентов в курсе 0 в коллекции 6 раз.
renderAll: function () {
this.collection.each(this.render);
$('#spnStdntCourseName').text('Students Enrolled in ' + this.collection.at(0).get("Name"));
this.students.fetch({ data: $.param({ courseId: this.collection.at(0).get("Id") }) });
SubQuestion
В & quot; CourseList & quot; у нас есть функция инициализации, как показано ниже
initialize: function () {
this.students = new Students();
var studentList = new StudentList({
collection: this.students,
el: '#studentsList'
});
Список студентов приведен ниже
<div id="studentsList" class="box">
<div class="box-head">
<h2 class="left">
<span id="spnStdntCourseName"></span>
</h2>
</div>
<div>
<input type="text" id="txtNewStudent" placeholder="Add New Student" />
<button id = "btnAddStudent">+ Add</button>
</div>
</div>
всякий раз, когда я делаю это. $ el.html (& quot; & quot;) внутри функции рендерингаStudentList смотреть как ниже
var StudentList = Backbone.View.extend({
tagName: 'ul',
render: function (model) {
this.$el.html("");
var item = new StudentItem({ model: model });
this.$el.append(item.el);
},
......
Я теряю элементы button и textbox внутри элемента StudentsList, и ul не отображается при просмотре исходного кода в моем браузере, который я назвал tagName, но я вижу li, которое является tagName для представления studentItem. Можете ли вы сказать, что я делать неправильно
Спасибо за наше терпение