Usando o Event Aggregator para carregar uma view com um modelo diferente no backbone js

Eu sou novo no backbone.js começou com backbone há uma semana. Eu tive que fazer uma demonstração. A idéia principal por trás disso é quando a página é carregada, eu preciso mostrar os cursos e, por padrão, a lista de alunos para o primeiro curso da lista. Aqui está o código para exibir a lista de cursos que está emcourse.js Arquivo

//Modelo

  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'
    });
});

Por favor, dê uma olhada no'courseClicked' função dentroCourseItem Visualizar, é suposto carregar a lista de alunos quando um item do curso é clicado.

Agora eu tenho meuAluna modelo e visualizações em students.js como abaixo

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'
    });      
});

tão dentro do document.ready eu tenhostudentDetails variável que carrega a lista de alunos.Aqui está o meu problema a partir de agora eu carreguei a lista de alunos no carregamento da página, passando algum parâmetro de código rígido dentro buscar como abaixo

 this.collection.fetch({ data: $.param({ courseId: 11 }) });

mas o que eu preciso mostrar é, a lista de alunos para o primeiro curso na visão do curso de curso quando a página é carregada, e em fases posteriores, a lista de alunos para cada item de curso clicou.Para esse fim, se você pode lembrar no função "courseClicked" dentro da visão "CourseItem" no course.js, eu usei

 Vent.trigger('studentDetails',"how to load student list from here based on courseID...?");

studentDetails é o var que inicializei no students.js (no código acima) assim

window.students = new Students();
$(function () {
var studentDetails = new StudentList({
    collection: window.students,
    el: '#studentsList'
});      
}); 

Então, quando eu acionar o alunoDetalhes eu definitivamente estou precisando do modelo de aluno dentro da minha funçãoClicked, que não está disponível nesse contexto. Acredito que vocês entenderam o meu problema da explicação acima. Então, como eu corrijo isso ...? É a abordagem que eu segui errado ..? Qualquer boa alternativa, precisa de sugestões. Espero que não haja muito barulho na pergunta.

EDITAR

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);   
}
})

Eu fiz as seguintes alterações

1.estudantes na coleção para este.estudantes (dentro inicializar de "CourseList" view) no código abaixo

initialize: function () {
    this.students = new Students();
    var studentList = new StudentList({
        collection: this.students,
        el: '#studentsList'
    });

2. Eu tenho buscado os alunos dentro da função renderAll ao invés de renderizar função porque para cada item do curso que é buscado o aluno também é buscado. Quero dizer, se existem 6 cursos eu consigo ver os alunos do curso 0 na coleção 6 vezes.

 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") }) });

Subquestão

Na "CourseList" temos a função inicializar como abaixo

 initialize: function () {
    this.students = new Students();
    var studentList = new StudentList({
        collection: this.students,
        el: '#studentsList'
    });

The studentsList el é como abaixo

<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> 

sempre que eu fizer isso. $ el.html ("") dentro da função render deStudentList veja como abaixo

var StudentList = Backbone.View.extend({
tagName: 'ul',

render: function (model) {
this.$el.html("");
    var item = new StudentItem({ model: model });
    this.$el.append(item.el);
},
......

Eu perco o botão e os elementos da caixa de texto dentro do studentsList el, e o ul não é mostrado quando eu vejo o código fonte no meu navegador que eu mencionei como tagName, mas eu vejo li que é tagName para studentItem view.Você diz o que eu sou fazendo errado

Obrigado pela nossa paciência

questionAnswers(1)

yourAnswerToTheQuestion