导航视图Backbone不会删除模型

时间:2016-03-05 06:52:47

标签: javascript backbone.js

问题以下列方式复制:

  1. 导航至路线Initial State
  2. 导航Go to other route
  3. 导航回Go back
  4. 每当我向后导航时,模型都不会被渲染。我想那是因为这个事件没有被触发:

    this.listenTo(this.collection, 'add', this.addOne);
    this.listenTo(this.collection, 'reset', this.addAll);
    

    这是我的路由器:

        routes: {
            ''               : 'home',
            'home'           : 'home',
            'departments'    : 'departments',
            ...
        },
    
        home: function(){
            var view = new app.HomeView();
            this.showView(view);
        },
    
        departments: function(){
            var view = new app.DepartmentsView();
            this.showView(view);
        }, 
        showView: function(view){
             if (this.currentView){
              this.currentView.clean();
            }
    
            this.currentView = view;
            this.currentView.render()
    
            $('#container').html(this.currentView.el);
        }
    

    这是我干净的方法:

    Backbone.View.prototype.clean = function () {
        this.remove();
        this.unbind();
        _.each(this.subViews, function(subView){
            subView.clean();
            if(subView.onClose){ subView.onClose() }
        });
    };
    

    这是子视图上的onClose方法:

    onClose: function(){
            this.model.off('change',this.render);
            this.model.off('destroy',this.remove);
            console.log('unbinding');
        }
    

    我将所有子视图保存在数组中,然后在导航时关闭。我真的没有找出这种问题的根本原因。

    我非常绝望,因为我已尝试过Derick Bailey的所有帖子并通过Backbone的文档,并且无法解决这个问题。

    ------ -------- EDIT 该视图的组成如下:

    1. 父视图:包含不带行的表,标题。
    2. 子视图:哪些行 - &gt; <tr>
    3. 模态视图:这是一个 包含创建模型的表单的视图
    4. 这是我的回购,如果你想看看。实际上再现一些最小的东西是在问题中发布的大量代码。 REPO

      我很感激你的帮助。

1 个答案:

答案 0 :(得分:1)

这是我怀疑问题所在。您的Departments集合仅实例化一次app.Departments = new DepartmentList();。然后在DepartmentsView初始化函数中,指定this.collection = app.Departments;这意味着第二次转到DepartmentsView时,您将其集合分配给已有模型的现有集合。当您调用fetch()时,Backbone会检测到没有新模型(因为您已经在集合中有模型),因此不会触发添加事件。

您可以做的一件事是使用重置fetch({reset:true})来调用fetch。然后,当获取成功时,它将清除现有模型并重新添加它们,并触发重置。

由于您已拥有模型,因此重置有点浪费。另一个解决方案是检查集合中是否包含init函数中的任何模型,如果它然后再渲染它们。像这样的东西

initialize: function(){
        this.collection = app.Departments;
        this.subViews = [];

        if(this.collection.size() > 0)
            this.collection.each(this.addOne, this);

        this.listenTo(this.collection, 'add', this.addOne);
        this.listenTo(this.collection, 'reset', this.addAll);

        this.collection.fetch();
    },

然后,fetch将添加它在获取成功时找到的任何新模型。

编辑:不是最干净的解决方案,但它应该有效。

initialize: function(){
        this.collection = app.Departments;
        this.subViews = [];

        if(this.collection.size() > 0)
            this.preExisting = true;

        this.listenTo(this.collection, 'add', this.addOne);
        this.listenTo(this.collection, 'reset', this.addAll);

        this.collection.fetch();
    },

    render: function(){
        this.$el.html( this.template({title: 'Departamentos',header_fields: this.tableHeader}) );
        this.$tbody = this.$('#rows');

        if(this.preExisting)
            this.collection.each(this.addOne, this);

        return this;
    },