BackboneJS渲染问题

BackboneJS渲染问题,第1张

BackboneJS渲染问题 视图的部分渲染

为了最大程度地减少DOM层次结构的完整呈现,您可以在DOM中设置特殊的节点,以反映给定属性的更新。

让我们使用这个简单的Underscore模板,一个名称列表:

<ul>  <% _(children).each(function(model) { %>    <li>        <span ><%= model.name %></span> :        <span ><%= model.name %></span>    </li>  <% }); %></ul>

注意class

model-<%= model.cid %>-name
,这将是我们的注入点。

然后,我们可以定义一个基本视图(或修改Backbone.View),以便在更新这些节点时为其添加适当的值:

var V = Backbone.View.extend({    initialize: function () {        // bind all changes to the models in the collection        this.collection.on('change', this.autoupdate, this);    },    // grab the changes and fill any zone set to receive the values    autoupdate: function (model) {        var _this = this, changes = model.changedAttributes(), attrs = _.keys(changes);        _.each(attrs, function (attr) { _this.$('.model-' + model.cid + '-' + attr).html(model.get(attr));        });    },    // render the complete template    // should only happen when there really is a dramatic change to the view    render: function () {        var data, html;        // build the data to render the template        // this.collection.toJSON() with the cid added, in fact        data = this.collection.map(function (model) { return _.extend(model.toJSON(), {cid: model.cid});        });        html = template({children: data});        this.$el.html(html);        return this;    }});

代码会有所不同,以适应模型而不是集合。与http://jsfiddle.net/nikoshr/cfcDX/一起玩的小提琴

限制DOM *** 作

将渲染委派给子视图可能会花费很多,它们的HTML片段必须插入到父视图的DOM中。看看这个jsperf测试,比较不同的渲染方法

其要点在于,生成完整的HTML结构然后应用视图比构建视图和子视图然后级联呈现要快得多。例如,

<script id="tpl-table" type="text/template">    <table>        <thead> <tr>     <th>Row</th>     <th>Name</th> </tr>        </thead>        <tbody>        <% _(children).each(function(model) { %> <tr id='<%= model.cid %>'>     <td><%= model.row %></td>     <td><%= model.name %></td> </tr>        <% }); %>        </tbody>     </table></script>var ItemView = Backbone.View.extend({});var ListView = Backbone.View.extend({    render: function () {        var data, html, $table, template = this.options.template;        data = this.collection.map(function (model) { return _.extend(model.toJSON(), {     cid: model.cid });        });        html = this.options.template({ children: data        });        $table = $(html);        this.collection.each(function (model) { var subview = new ItemView({     el: $table.find("#" + model.cid),     model: model });        });        this.$el.empty();        this.$el.append($table);        return this;    }});var view = new ListView({    template: _.template($('#tpl-table').html()),    collection: new Backbone.Collection(data)});

http://jsfiddle.net/nikoshr/UeefE/

请注意,jsperf显示了可以将模板拆分为子模板而不会带来太多损失,这将使您能够为行提供部分渲染。

值得一提的是,不要在连接到DOM的节点上工作,这将导致不必要的重排。在 *** 作它之前,要么创建一个新的DOM,要么分离该节点。

Squash zombies

德里克·贝利(DerickBailey)撰写了一篇出色的文章,主题是消除僵尸观点

基本上,您必须记住,丢弃视图时,必须取消绑定所有侦听器并执行任何其他清除 *** 作,例如销毁jQuery插件实例。我使用的是类似于Derick在Backbone.Marionette中使用的方法的组合:

var baseView = Backbone.View.extend({    initialize: function () {        // list of subviews        this.views = [];    },    // handle the subviews    // override to destroy jQuery plugin instances    unstage: function () {        if (!this.views) { return;        }        var i, l = this.views.length;        for (i = 0; i < l; i = i + 1) { this.views[i].destroy();        }        this.views = [];    },    // override to setup jQuery plugin instances    stage: function () {    },    // destroy the view    destroy: function () {        this.unstage();        this.remove();        this.off();        if (this.collection) { this.collection.off(null, null, this);        }        if (this.model) { this.model.off(null, null, this);        }    }});

更新我之前的示例以使行具有可拖动的行为,如下所示:

var ItemView = baseView.extend({    stage: function () {        this.$el.draggable({ revert: "invalid", helper: "clone"        });    },    unstage: function () {        this.$el.draggable('destroy');        baseView.prototype.unstage.call(this);    }});var ListView = baseView.extend({    render: function () {       //same as before        this.unstage();        this.collection.each(function (model) { var subview = new ItemView({     el: $table.find("#" + model.cid),     model: model }); subview.stage(); this.views.push(subview);        }, this);        this.stage();        this.$el.empty();        this.$el.append($table);        return this;    }});

http://jsfiddle.net/nikoshr/yL7g6/

销毁根视图将遍历视图的层次结构并执行必要的清理。

注意:对JS代码感到抱歉,我对Coffeescript不够熟悉,无法提供准确的摘要。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5087745.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-16
下一篇 2022-11-16

发表评论

登录后才能评论

评论列表(0条)

保存