Javascript 主干更改事件未触发

Javascript 主干更改事件未触发,javascript,backbone.js,backbone-views,backbone-events,Javascript,Backbone.js,Backbone Views,Backbone Events,在我的web应用程序中,我有一个混合了普通标准属性(字符串、布尔值等)和集合的模型。在应用程序中,用户可以创建一个组并向该组添加一个项目。该组正在与模型一起收集。我可以向组中添加和删除项目,这非常好,以至于我可以在日志记录和数据库中看到正在添加或删除的项目 要将项目添加到组中,我打开一个模式,然后单击该模式中的按钮触发model.save(),这将触发一个更改事件。但是,如果我添加用户,然后在不重新加载页面的情况下删除,则不会触发更改,为什么会这样?这是模态视图 模态视图 Views.Organ

在我的web应用程序中,我有一个混合了普通标准属性(字符串、布尔值等)和集合的模型。在应用程序中,用户可以创建一个组并向该组添加一个项目。该组正在与模型一起收集。我可以向组中添加和删除项目,这非常好,以至于我可以在日志记录和数据库中看到正在添加或删除的项目

要将项目添加到组中,我打开一个模式,然后单击该模式中的按钮触发model.save(),这将触发一个更改事件。但是,如果我添加用户,然后在不重新加载页面的情况下删除,则不会触发更改,为什么会这样?这是模态视图

模态视图

Views.OrganisastionEditView = Backbone.View.extend({

    className : 'modal-body',

    template: _.template( $('#tpl-edit-organisation').html() ),

    events: {
        "click .js-add-member" : "addMember",
        "click .js-add-client" : "addClient",
        "click .js-add-project" : "addProject",
        "click .js-add-team" : "addTeam",
        "click .search-results a" : "selectSearchResult",
        "click .js-remove-pill" : "removeAttribute",
        "submit .edit-organisation" : "saveOrganisation",
        "click .js-remove-delete" : "deleteOrganisation",
        "click .js-make-admin" : "changeAdmin"

    },

    initialize: function() {
        //this.listenTo(this.model, 'change', this.snyc);
        this.listenTo(this.model.get('members'), 'change', this.changeMember);
        this.render();
    },

    render: function() {
        var self = this;
    //  this.model.initialize();
        $('#myModal').on('hidden.bs.modal', function () {
            self.remove();
            Pops.Routes.Application.navigate('/groups', { trigger: false } );
        });

        this.$el.html( this.template({
            organisation: this.model.toJSON()
        })).insertAfter('.modal-header');

        var organisationProjectsView = new Views.GroupsProjectsViews({
            collection: this.model.get('projects')
        });

        var organisationClientsView = new Pops.Views.GroupsClientsViews({
            collection: this.model.get('clients')
        });

        var organisationMembersView = new Views.GroupsMembersAdminViews({
            collection: this.model.get('members')
        });

        var organisationTeamsView = new Views.GroupsTeamsViews({
            collection: this.model.get('teams')
        });

        $("#myModal").modal();
    },

    deleteOrganisation: function(e) {
        e.preventDefault();
        this.model.destroy();
        $("#myModal").modal('hide');
        this.remove();
    },

    removeAttribute: function(e) {
        e.preventDefault();
        var element = $(e.currentTarget);
        switch(element.data('type')) {
            case "project":
                console.log(this.model.get('projects'));
                this.model.get('projects').remove(element.data('id'));
                element.parents('.avatar-pill').remove();
            break;

            case "client":
                this.model.get('clients').remove(element.data('id'));
                element.parents('.avatar-pill').remove();
            break;
        }
    },

    addMember: function(e) {
        e.preventDefault();

        var element = $(e.currentTarget);

        this.$('.search').parent().children().show();
        this.$('.search').first().remove();

        //element.parent().children().hide();

        var search = new Views.SearchView({
            collection: new Collections.Users,
            type : "users",
            merge: false
        });

        element.parent().append(search.render().el);
    },

    addProject: function(e) {
        e.preventDefault();

        var element = $(e.currentTarget);

        this.$('.search').parent().children().show();
        this.$('.search').first().remove();

        //element.parent().children().hide();

        var search = new Views.SearchView({
            collection: new Collections.Projects,
            type : "projects",
            merge: false
        });

        element.parent().append(search.render().el);
    },



    selectSearchResult: function(e) {
        e.preventDefault();

        var element = $(e.currentTarget),
            self = this;

        switch( element.data('type')) {

            case "project":
                var project = new Models.Project({ id: element.data('id')});
                project.fetch({
                    success: function() {
                        self.model.get('projects').add(project);
                        console.log(self.model.get('projects'));
                        var model = self.model;
                        self.$('.search').hide();
                        self.$('button').show();
                        var projectsDetails = new Views.ProjectNamePillView({
                            model : project
                        });
                        self.$('.search').parent().append( projectsDetails.render().el );
                        self.$('.search').remove();
                    }

                });
            break;

        }
    },

    saveOrganisation: function(e) {
        e.preventDefault();

        var element = $(e.currentTarget);
        var data = element.serializeJSON();

        this.model.set(data);

        this.model.save();

    },

});
    Views.OrganisationView = Backbone.View.extend({

    tagName: 'div',
    className:'group group--panel col-sm-3',

    template : _.template( $('#tpl-single-group').html() ),

    events: {
        "click a[data-type=organisation], button[data-type=organisation]" : "edit",
        "click .js-delete-group" : "removeOrganisation",
    },

    initialize: function() {
        this.listenTo(this.model, 'change', this.render);
        //this.listenTo(this.model, 'change', this.render);
        this.listenTo(this.model, 'destroy', this.removeView);
    },

    render: function() {
        console.log('getting fired');
        this.$el.html( this.template({
            group: this.model.toJSON()
        }));

        return this;
    },

    removeView: function() {
        this.remove();
    },

    removeOrganisation: function(e) {
        this.model.destory();
        this.remove();
    },

    edit: function(e) {
        e.preventDefault();
        Routes.Application.navigate('/organisation/edit/' + this.model.get('id'), { trigger: false } );
        var editClient = new Views.OrganisastionEditView({
            model: this.model
        });
    }

});
单一模型视图

Views.OrganisastionEditView = Backbone.View.extend({

    className : 'modal-body',

    template: _.template( $('#tpl-edit-organisation').html() ),

    events: {
        "click .js-add-member" : "addMember",
        "click .js-add-client" : "addClient",
        "click .js-add-project" : "addProject",
        "click .js-add-team" : "addTeam",
        "click .search-results a" : "selectSearchResult",
        "click .js-remove-pill" : "removeAttribute",
        "submit .edit-organisation" : "saveOrganisation",
        "click .js-remove-delete" : "deleteOrganisation",
        "click .js-make-admin" : "changeAdmin"

    },

    initialize: function() {
        //this.listenTo(this.model, 'change', this.snyc);
        this.listenTo(this.model.get('members'), 'change', this.changeMember);
        this.render();
    },

    render: function() {
        var self = this;
    //  this.model.initialize();
        $('#myModal').on('hidden.bs.modal', function () {
            self.remove();
            Pops.Routes.Application.navigate('/groups', { trigger: false } );
        });

        this.$el.html( this.template({
            organisation: this.model.toJSON()
        })).insertAfter('.modal-header');

        var organisationProjectsView = new Views.GroupsProjectsViews({
            collection: this.model.get('projects')
        });

        var organisationClientsView = new Pops.Views.GroupsClientsViews({
            collection: this.model.get('clients')
        });

        var organisationMembersView = new Views.GroupsMembersAdminViews({
            collection: this.model.get('members')
        });

        var organisationTeamsView = new Views.GroupsTeamsViews({
            collection: this.model.get('teams')
        });

        $("#myModal").modal();
    },

    deleteOrganisation: function(e) {
        e.preventDefault();
        this.model.destroy();
        $("#myModal").modal('hide');
        this.remove();
    },

    removeAttribute: function(e) {
        e.preventDefault();
        var element = $(e.currentTarget);
        switch(element.data('type')) {
            case "project":
                console.log(this.model.get('projects'));
                this.model.get('projects').remove(element.data('id'));
                element.parents('.avatar-pill').remove();
            break;

            case "client":
                this.model.get('clients').remove(element.data('id'));
                element.parents('.avatar-pill').remove();
            break;
        }
    },

    addMember: function(e) {
        e.preventDefault();

        var element = $(e.currentTarget);

        this.$('.search').parent().children().show();
        this.$('.search').first().remove();

        //element.parent().children().hide();

        var search = new Views.SearchView({
            collection: new Collections.Users,
            type : "users",
            merge: false
        });

        element.parent().append(search.render().el);
    },

    addProject: function(e) {
        e.preventDefault();

        var element = $(e.currentTarget);

        this.$('.search').parent().children().show();
        this.$('.search').first().remove();

        //element.parent().children().hide();

        var search = new Views.SearchView({
            collection: new Collections.Projects,
            type : "projects",
            merge: false
        });

        element.parent().append(search.render().el);
    },



    selectSearchResult: function(e) {
        e.preventDefault();

        var element = $(e.currentTarget),
            self = this;

        switch( element.data('type')) {

            case "project":
                var project = new Models.Project({ id: element.data('id')});
                project.fetch({
                    success: function() {
                        self.model.get('projects').add(project);
                        console.log(self.model.get('projects'));
                        var model = self.model;
                        self.$('.search').hide();
                        self.$('button').show();
                        var projectsDetails = new Views.ProjectNamePillView({
                            model : project
                        });
                        self.$('.search').parent().append( projectsDetails.render().el );
                        self.$('.search').remove();
                    }

                });
            break;

        }
    },

    saveOrganisation: function(e) {
        e.preventDefault();

        var element = $(e.currentTarget);
        var data = element.serializeJSON();

        this.model.set(data);

        this.model.save();

    },

});
    Views.OrganisationView = Backbone.View.extend({

    tagName: 'div',
    className:'group group--panel col-sm-3',

    template : _.template( $('#tpl-single-group').html() ),

    events: {
        "click a[data-type=organisation], button[data-type=organisation]" : "edit",
        "click .js-delete-group" : "removeOrganisation",
    },

    initialize: function() {
        this.listenTo(this.model, 'change', this.render);
        //this.listenTo(this.model, 'change', this.render);
        this.listenTo(this.model, 'destroy', this.removeView);
    },

    render: function() {
        console.log('getting fired');
        this.$el.html( this.template({
            group: this.model.toJSON()
        }));

        return this;
    },

    removeView: function() {
        this.remove();
    },

    removeOrganisation: function(e) {
        this.model.destory();
        this.remove();
    },

    edit: function(e) {
        e.preventDefault();
        Routes.Application.navigate('/organisation/edit/' + this.model.get('id'), { trigger: false } );
        var editClient = new Views.OrganisastionEditView({
            model: this.model
        });
    }

});

更改事件是在模型本身而不是其属性上触发的。但是,您可以使用
change:[属性]
事件命名格式来侦听特定属性的更改

在您的示例中,您将更改:

this.listenTo(this.model.get('members'), 'change', this.changeMember);
看起来像:

this.listenTo(this.model, 'change:members', this.changeMember);

检查。

删除组织中有一个输入错误:
this.model.destory();