在 Backbone.js 中触发嵌套模型事件

发布于 2024-12-20 15:18:49 字数 7022 浏览 0 评论 0原文

问题:当我尝试触发任何子事件(文件)时,父事件也会随之触发(文件)。

我的关系是这样的: Project ---> (许多)文件(如果只是文件夹)---> (很多)文件等等(如果只是文件夹)

我的想法是使用 Backbone.Js 构建文件夹树。

我的代码如下:

(function ($){

//Models ********************************************************************

window.Project = Backbone.Model.extend({

    defaults : {
      state : "collapsed"
    },

    initialize : function(){
        this.files = new Files ;
        //this.files.url = "rest/operations/files/0.json";
        this.files.url = this.get("project_id")+"/rest/operations/files/0.json";
        //this.files.fetch();
    } , 

    isCollapsed : function (){
        return (this.get("state") === "collapsed");
    },

    isExpanded : function(){
        return (!this.isCollapsed());
    },

    collapse : function(){
        this.set({
            'state' : 'collapsed'
        });
    },

    expand : function(){
        this.set({
            'state' : 'expanded'
        });
    }

});


window.File = Backbone.Model.extend({

    defaults : {
      state : "collapsed" ,
    },

    initialize : function(){
        //if(this.isItHasChild() && this.isItFolder()){  //check the child from the server
        if(this.isItFolder()){
            //means has files as child
            this.files = new Files ; 
            //this.files.url = "rest/operations/files/"+this.get("file_id")+".json";
            //this.files.url = this.get("project_id")+"/rest/operations/files/"+this.get("file_id")+".json";

            //test
            this.files.url = this.get("project_id")+"/rest/operations/files/0.json";
            //this.set({"modelCid" : this.cid});
        }    
    }, 

    isItHasChild : function (){
        return (this.get("isHasChild"));
    },

    isItFolder : function(){
        return (this.get("is_folder"));
    },

    isCollapsed : function (){
        return (this.get("state") === "collapsed");
    },

    isExpanded : function(){
        return (!this.isCollapsed());
    },

    collapse : function(){
        this.set({
            'state' : 'collapsed'
        });
    },

    expand : function(){
        this.set({
            'state' : 'expanded'
        });
    }

});


//Collections *************************************************************

window.Projects = Backbone.Collection.extend({
    //find a way to load the project number
    model : Project,
    url : "1/rest/operations/projects.json"
});


window.Files = Backbone.Collection.extend({
    model : File
});


//Views **********************************************************************

$(document).ready(function(){

    window.ProjectView = Backbone.View.extend({

        template : _.template($("#project-template").html()),

        initialize : function(){
            _.bindAll(this,'render','expand','collapse','renderFile','btn_clicked');
            //this.template = _.template($("#project-template").html());
            this.model.files.bind('reset',this.render);
        } , 

        events : {
            'click .project_btn_expand_collapse' : "btn_clicked"
        } , 

        render : function(){
            //console.log(this.model.cid);
            $(this.el).html(this.template(this.model.toJSON()));
            this.model.files.each(this.renderFile);
            return this ;
        } , 

        btn_clicked : function(){
            //alert(this.model.cid+" "+this.model.get('state'));
            if(this.model.isCollapsed()){
                this.expand();
            }else {
                //this.collapse();
            }
        },

        expand : function (){
            this.model.files.fetch();
            this.updateState();
        } , 

        collapse : function (){
          this.model.files.reset();
          this.updateState();
        },

        updateState : function(){
            if(this.model.isCollapsed()){
                this.model.expand();
            } else {
                this.model.collapse();
            }
        },

        renderFile : function (file){
            var view = new FileView({
                model : file , 
                id : file.cid , 
            });

            this.$("ul").append(view.render().el);
        }

    });


    window.FileView = Backbone.View.extend({

        template : _.template($("#file-template").html()),
        tagName : 'li',

        events : {
            "click" : "btn_clicked"
        },

        initialize : function(){
            _.bindAll(this,'render','expand','collapse','renderFile','btn_clicked');
            console.log(this.model.cid);

            //if(this.model.isItHasChild() && this.model.isItFolder()){ //as what we have said before we have to check the server
            if(this.model.isItFolder()){
                this.model.files.bind('reset',this.render);
            }  
        },

        render : function(){
            //console.log(this.model.cid);
            $(this.el).html(this.template(this.model.toJSON()));
            this.model.files.each(this.renderFile);
            return this ;
        },

        btn_clicked : function(){
            alert(this.model.cid+" "+this.model.get('state'));
            if(this.model.isCollapsed()){
                this.expand();
            }else {
                //this.collapse();
            }
        },

        renderFile : function (file){
            var view = new FileView({
                model : file , 
                id : file.cid , 
            });
            $(this.el).append("<ul></ul>");
            this.$("ul").append(view.render().el);
        },

        expand : function (){
            this.model.files.fetch();
            this.updateState();
        }, 

        collapse : function (){
          this.model.files.reset();
          this.updateState();
        },

        updateState : function(){
            if(this.model.isCollapsed()){
                this.model.expand();
            } else {
                this.model.collapse();
            }
        }

    });


    //run the application *********************************************************************************

    window.IDEHTML5 = Backbone.Router.extend({

        routes : {
            "" : "index", 
            ":id" : "getProjectID"
        },    

        initialize: function(){
        },

        getProjectID : function(id){
            alert(id);
        },

        index : function(){
            var projects = new Projects();
            projects.fetch({
                success : function(){
                    var project = projects.at(0);
                    this.project_view = new ProjectView({model : project});
                    $("#container").html(this.project_view.render().el);
                },
                error : function(){ }
            }); 
        }

    });


    //run the application

    window.App = new IDEHTML5();
    //Backbone.history.start({pushState: true});
    Backbone.history.start();

});


})(jQuery);

Problem: When I'm trying to fire any child event (Files), the parent's event is fired with it (Files).

My relation is like this: Project ---> (Many)Files(If is only folder) ---> (Many)Files and so on(If is only folder)

My idea is to construct folder tree using Backbone.Js.

My code as follows:

(function ($){

//Models ********************************************************************

window.Project = Backbone.Model.extend({

    defaults : {
      state : "collapsed"
    },

    initialize : function(){
        this.files = new Files ;
        //this.files.url = "rest/operations/files/0.json";
        this.files.url = this.get("project_id")+"/rest/operations/files/0.json";
        //this.files.fetch();
    } , 

    isCollapsed : function (){
        return (this.get("state") === "collapsed");
    },

    isExpanded : function(){
        return (!this.isCollapsed());
    },

    collapse : function(){
        this.set({
            'state' : 'collapsed'
        });
    },

    expand : function(){
        this.set({
            'state' : 'expanded'
        });
    }

});


window.File = Backbone.Model.extend({

    defaults : {
      state : "collapsed" ,
    },

    initialize : function(){
        //if(this.isItHasChild() && this.isItFolder()){  //check the child from the server
        if(this.isItFolder()){
            //means has files as child
            this.files = new Files ; 
            //this.files.url = "rest/operations/files/"+this.get("file_id")+".json";
            //this.files.url = this.get("project_id")+"/rest/operations/files/"+this.get("file_id")+".json";

            //test
            this.files.url = this.get("project_id")+"/rest/operations/files/0.json";
            //this.set({"modelCid" : this.cid});
        }    
    }, 

    isItHasChild : function (){
        return (this.get("isHasChild"));
    },

    isItFolder : function(){
        return (this.get("is_folder"));
    },

    isCollapsed : function (){
        return (this.get("state") === "collapsed");
    },

    isExpanded : function(){
        return (!this.isCollapsed());
    },

    collapse : function(){
        this.set({
            'state' : 'collapsed'
        });
    },

    expand : function(){
        this.set({
            'state' : 'expanded'
        });
    }

});


//Collections *************************************************************

window.Projects = Backbone.Collection.extend({
    //find a way to load the project number
    model : Project,
    url : "1/rest/operations/projects.json"
});


window.Files = Backbone.Collection.extend({
    model : File
});


//Views **********************************************************************

$(document).ready(function(){

    window.ProjectView = Backbone.View.extend({

        template : _.template($("#project-template").html()),

        initialize : function(){
            _.bindAll(this,'render','expand','collapse','renderFile','btn_clicked');
            //this.template = _.template($("#project-template").html());
            this.model.files.bind('reset',this.render);
        } , 

        events : {
            'click .project_btn_expand_collapse' : "btn_clicked"
        } , 

        render : function(){
            //console.log(this.model.cid);
            $(this.el).html(this.template(this.model.toJSON()));
            this.model.files.each(this.renderFile);
            return this ;
        } , 

        btn_clicked : function(){
            //alert(this.model.cid+" "+this.model.get('state'));
            if(this.model.isCollapsed()){
                this.expand();
            }else {
                //this.collapse();
            }
        },

        expand : function (){
            this.model.files.fetch();
            this.updateState();
        } , 

        collapse : function (){
          this.model.files.reset();
          this.updateState();
        },

        updateState : function(){
            if(this.model.isCollapsed()){
                this.model.expand();
            } else {
                this.model.collapse();
            }
        },

        renderFile : function (file){
            var view = new FileView({
                model : file , 
                id : file.cid , 
            });

            this.$("ul").append(view.render().el);
        }

    });


    window.FileView = Backbone.View.extend({

        template : _.template($("#file-template").html()),
        tagName : 'li',

        events : {
            "click" : "btn_clicked"
        },

        initialize : function(){
            _.bindAll(this,'render','expand','collapse','renderFile','btn_clicked');
            console.log(this.model.cid);

            //if(this.model.isItHasChild() && this.model.isItFolder()){ //as what we have said before we have to check the server
            if(this.model.isItFolder()){
                this.model.files.bind('reset',this.render);
            }  
        },

        render : function(){
            //console.log(this.model.cid);
            $(this.el).html(this.template(this.model.toJSON()));
            this.model.files.each(this.renderFile);
            return this ;
        },

        btn_clicked : function(){
            alert(this.model.cid+" "+this.model.get('state'));
            if(this.model.isCollapsed()){
                this.expand();
            }else {
                //this.collapse();
            }
        },

        renderFile : function (file){
            var view = new FileView({
                model : file , 
                id : file.cid , 
            });
            $(this.el).append("<ul></ul>");
            this.$("ul").append(view.render().el);
        },

        expand : function (){
            this.model.files.fetch();
            this.updateState();
        }, 

        collapse : function (){
          this.model.files.reset();
          this.updateState();
        },

        updateState : function(){
            if(this.model.isCollapsed()){
                this.model.expand();
            } else {
                this.model.collapse();
            }
        }

    });


    //run the application *********************************************************************************

    window.IDEHTML5 = Backbone.Router.extend({

        routes : {
            "" : "index", 
            ":id" : "getProjectID"
        },    

        initialize: function(){
        },

        getProjectID : function(id){
            alert(id);
        },

        index : function(){
            var projects = new Projects();
            projects.fetch({
                success : function(){
                    var project = projects.at(0);
                    this.project_view = new ProjectView({model : project});
                    $("#container").html(this.project_view.render().el);
                },
                error : function(){ }
            }); 
        }

    });


    //run the application

    window.App = new IDEHTML5();
    //Backbone.history.start({pushState: true});
    Backbone.history.start();

});


})(jQuery);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爺獨霸怡葒院 2024-12-27 15:18:49
this.files = new Files ;

应该是:

this.files = new Files() ;
this.files = new Files ;

Should be:

this.files = new Files() ;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文