0

我正在使用 Backbone.js 和 Underscore.js(以及常见的嫌疑人,例如 JQuery 和 require.js)来创建 Web 应用程序。Web 应用程序的部分逻辑涉及加载 HTML 视图/模板。我编写了一个机制(基于在此处和其他地方找到的脚本),如下所示。

var some_View = Backbone.View.extend(
    {
        initialize:function(){this.render();},
        render:function(){
                var renderedElement = this.$el.html(something.render("someView"));
            }

    }
)

var someView=new some_View( {el:$("#some_DIV_container")} );

其中something.render("someView")是一种实际进行渲染的方法。该方法执行 AJAX 调用并将加载的结果插入到传递的 DIV (some_DIV_container) 中:

// code in the "something" object
render:function(tmpl_name,tmpl_data){
    console.log("loading view..." + tmpl_name);
    // this method renders a view. from the /views folder.
    if ( !this.render.tmpl_cache ) { 
        this.render.tmpl_cache = {};
    }
    if ( ! this.render.tmpl_cache[tmpl_name] ) {
        var tmpl_dir = 'views';
        var tmpl_url = tmpl_dir + '/' + tmpl_name + '.html';
        var tmpl_string;
        $.ajax({
            url: tmpl_url,
            method: 'GET',
            dataType:'html',
            async: false,
            success: function(data) {
                tmpl_string = data;
            }
        });
    this.render.tmpl_cache[tmpl_name] = _.template(tmpl_string);
    }
    console.log(" this.render.tmpl_cache[tmpl_name](tmpl_data) = "+ this.render.tmpl_cache[tmpl_name](tmpl_data));      
    return this.render.tmpl_cache[tmpl_name](tmpl_data);
}

代码就像一个魅力,除了每次我创建一个新视图时,我必须创建一些扩展 Backbone.View 的变量,并创建另一个扩展 Backbone.View 的变量。换句话说,要加载的 HTML 文件的名称“someView”是静态的。我想将 HTML 模板的名称传递给动态加载。我只是看不到如何以 some_View 的编写方式传递参数。

我认为(看起来)

  • Backbone.View.Extend() 返回一些函数对象
  • 我们使用el将 jQuery 引用传递给要插入 HTML 模板/视图代码的容器
  • 当“some_View”被渲染时,我们调用something.render,它将HTML加载并返回到this.$el的html()方法中,我相信这本质上是我想要插入内容的已解析的div。内容被插入。

所以简而言之,我想优化这段代码,这样我就不必在每次想要创建视图时重复创建扩展backbone.view.extend 的变量并实例化它。

有什么想法吗?这是一个代码难题!

谢谢

4

2 回答 2

1

所以你想为所有视图重用相同的视图构造函数?似乎这仅适用于不会更改或没有用户输入的非常简单的视图。但是你也许可以做这样的事情,只需在创建视图时传入你想要使用的模板。

var some_View = Backbone.View.extend(
    {
        initialize:function(options){
            this.templateName = options.templateName;
            this.render();
        },
        render:function(){
                var renderedElement = this.$el.html(something.render(this.templateName));
            }

    }
)

var someView=new some_View( {el:$("#some_DIV_container"), templateName: 'someTemplate'} );
于 2013-02-07T18:44:49.070 回答
0

这是我使用的相关代码。(我也用Base.js做了一个类)

// this method is part of a javascript class called qq

var qq = Base.extend({

///other stuff///

render:function(tmpl_name,tmpl_data){
    console.log(" render(): rendering view " + tmpl_name + ".html");

    if ( !this.render.tmpl_cache ) { 
        this.render.tmpl_cache = {};
    }
    if ( ! this.render.tmpl_cache[tmpl_name] ) {
        var tmpl_dir = 'views'; // your directory
        var tmpl_url = tmpl_dir + '/' + tmpl_name + '.html';
        var tmpl_string;
        $.ajax({
            url: tmpl_url,
            method: 'GET',
            dataType:'html',
            async: false,
            success: function(data) {
                tmpl_string = data;
            }
        });
    this.render.tmpl_cache[tmpl_name] = _.template(tmpl_string);
    }

    return this.render.tmpl_cache[tmpl_name](tmpl_data);
}

});


var q=new qq(); // where the method above comes from
// define some initial parameters

q.viewParams={
    initialize:function(options){console.log("viewName = "+this.options.viewName);this.renderIt();},
    renderIt:function(){
        var renderedEl= this.$el.html(q.render(this.options.viewName));
        } 
    };

// load the recipient view
var x = Backbone.View.extend( q.viewParams );
q.recipientView = new x( {el:q.recipientBoxEl,viewName:"someView"}  );
于 2013-02-14T20:26:08.017 回答