Verwenden des Ereignisaggregators zum Laden einer Ansicht mit einem anderen Modell in Backbone-js

Ich bin neu bei backbone.js und habe vor einer Woche mit backbone angefangen. Ich musste eine Demo machen. Die Hauptidee dahinter ist, dass ich beim Laden der Seite die Kurse und standardmäßig die Studentenliste für den ersten Kurs in der Liste anzeigen muss. Hier ist der Code, um die Kursliste anzuzeigen, die sich in befindetcourse.js Datei

//Modell

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

Bitte werfen Sie einen Blick auf die'courseClicked' Funktion im InnerenCourseItem Anzeigen, es soll die Studentenliste laden, wenn ein Kurselement angeklickt wird.

Jetzt habe ich meineStudent Modell und Ansichten in students.js wie unten

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

also in document.ready habe ichstudentDetails Variable, die die Schülerliste lädt. Hier ist mein Problem, bis jetzt habe ich die Schülerliste beim Laden der Seite geladen, indem ich einen harten Code-Parameter in fetch übergeben habe, wie unten

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

Was ich aber anzeigen muss, ist die Studentenliste für den ersten Kurs in der Kurselistenansicht, wenn die Seite geladen wird, und in späteren Phasen die Studentenliste für jeden angeklickten Kurseintrag Die Funktion "courseClicked" in der Ansicht "CourseItem" in course.js habe ich verwendet

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

studentDetails ist die Variable, die ich in students.js (im obigen Code) so initialisiert habe

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

Wenn ich also studentDetails auslöse, benötige ich definitiv das Studentenmodell in meiner Funktion courseClicked, die in diesem Kontext nicht verfügbar ist. Ich glaube, ihr habt mein Problem aus der obigen Erklärung verstanden. Wie behebe ich das ...? Ist der Ansatz, dem ich gefolgt bin, falsch? Jede gute Alternative, brauche Vorschläge. Hoffe, es ist nicht zu viel Lärm in der Frage.

BEARBEITEN

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

Ich habe folgende Änderungen vorgenommen

1.students in collection to this.students (in der Ansicht "CourseList" initialisieren) im folgenden Code

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

2. Ich habe die Studenten in der renderAll-Funktion anstelle der render-Funktion abgerufen, da für jedes abgerufene Kurselement auch der Student abgerufen wird. Ich meine, wenn es 6 Kurse gibt, sehe ich die Studenten für den Kurs 0 sechs Mal in der Sammlung

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

Unterfrage

In der "CourseList" haben wir folgende Initialisierungsfunktion

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

Die Schülerliste ist wie folgt

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

wenn ich das tue. $ el.html ("") in der Renderfunktion vonStudentenliste siehe unten

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

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

Ich verliere die Schaltflächen- und Textfeldelemente in der studentsList el, und die ul wird nicht angezeigt, wenn ich den Quellcode in meinem Browser ansehe, den ich als tagName erwähnt habe, aber ich sehe li, der tagName für studentItem view ist. Können Sie sagen, was ich bin? falsch machen

Vielen Dank für Ihre Geduld

Antworten auf die Frage(1)

Ihre Antwort auf die Frage