首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >删除backbone中的孤立子视图

删除backbone中的孤立子视图
EN

Stack Overflow用户
提问于 2014-09-08 23:49:59
回答 2查看 752关注 0票数 0

我有一个骨干视图,其中包含各种研究项目的项目数据。

在这个视图中,我有一个按钮,当单击它时,它会执行一个名为“toggleChildView”的方法。此方法将子视图插入到主页中。

在子视图中,我正在侦听这样一个事件:用户单击页面上除包含研究子评论的元素之外的任何位置。

问题是,如果我关闭子视图,子视图实际上仍然在某个地方挂起,因为事件仍在触发,并且如果我打开和关闭子视图,它将触发多次。

例如,如果我打开和关闭儿童视图5次,在最终关闭后,事件仍将触发5次。

但如果它关闭了,它应该根本不会触发,并且只在打开时触发一次。

我认为我的问题最好是这样表达:

有没有办法摆脱“孤立”的子视图,并确保一次只打开一个子视图?

谢谢!

代码语言:javascript
运行
复制
Parent View:

    toggleChildView: function (e) {
        this.$('.displayresearchdata').toggle();
        this.$('.editdata').toggle();

        //initialize the research view into our main view
        var researchView = new researchView({ parent: this });
        self.$('.research').append(researchView.render().$el);
    },

    saveresearchdata: function (e) {
        this.model.save('researchData', this.$(".researchData").html());
    },



Child render method:

 initialize: function (options) {
        this.parent = options.parent;
    },

    render: function () {

        var self = this;
        this.$el.append(this.template());

        $("body").on("click", function (event) {
            if (!$(event.target).closest('.editdata').length) {
                if (self.parent.$('.editdata').is(":visible")) {
                    self.parent.saveresearchdata();
                }
            }
        });
            return this;
    },
EN

回答 2

Stack Overflow用户

发布于 2014-09-09 01:18:30

正如@mu太短指出的那样,你需要显式地删除()你添加的任何视图。

如果该查看器添加了一些自定义事件侦听器,您也应该将其删除。如果您使用事件侦听的view.listenTo(target, "eventname", this.functionName)风格,那么当您调用view.remove()时,由于stopListening()方法被调用,这些事件处理程序将被自动删除。

在您的代码中,问题是您没有保留对要添加的子视图的引用,因此无法对其调用remove。保留从父级到子级的内部引用,如下所示:

代码语言:javascript
运行
复制
//initialize the research view into our main view
if(this._researchView) {
  this._researchView.remove();
}

this._researchView = new researchView(...)
this.$(".research").empty().append(this._researchView.render().$el);

在追加之前注意empty的使用,如果你不想添加很多researchViews,一次只添加一个。如果你确实想要很多视图,那么你可以删除它,并将内部引用保留为一个数组。

票数 1
EN

Stack Overflow用户

发布于 2014-09-09 17:39:39

处理所谓的“僵尸”视图是使用Backbone时最棘手的部分之一,如果你有很多子视图,如果你没有正确地管理这些视图,它可能会成为一个真正的问题。关于这个主题的开创性帖子是this one by Derrik Bailey,但请注意,他引用的一些方法,如bind,现在已被弃用,转而支持listenTo

@CharlieBrown的答案将会起作用。但是,如果您计划创建其他视图和/或子视图,以下是一种可以在更大范围内进行设置的方法:

1)创建一个Baseview,所有其他视图都将从该基础视图扩展。

代码语言:javascript
运行
复制
var BaseView = Backbone.View.extend({
  //typical initialize and render functions 
  //...
  //Create the close method

    close: function () {
      if (this.onClose) this.onClose(); //looks for an onClose method in your subviews
      this.undelegateEvents();
      this.$el.off();
      this.$el.children().remove();
      this.$el.empty();
      this.stopListening();
    }
});

2)现在,在您的骨干路由器中,您可以创建一个trackView函数,该函数将从基本视图调用close()方法

代码语言:javascript
运行
复制
//within router
trackView: function (next) {
    console.log('now closing ' + next.cid);
    if (this.current) this.current.close();
    this.current = next;
},

3)现在应该从trackview内部调用路由器中的所有其他视图,如下所示:

代码语言:javascript
运行
复制
//within router
someView: function () {
        console.log('loading create user page');
        this.trackView(new someView()); //use trackView from step 2
    },

4)最后,在任何子视图中,确保添加一个'onClose()‘方法,在该方法中,您可以使用从Baseview继承的close方法关闭任何潜在的僵尸

代码语言:javascript
运行
复制
//inside a view

onClose: function() {
    if (this.couldBeAZombieView) this.couldBeAZombieView.close();
}

现在,您已经为一个更复杂的站点进行了设置。还有其他方法可以设置,但这是我熟悉的方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25728168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档