使用Handlebars绑定的主干UI模型

Backbone UI Model binding with Handlebars

本文关键字:UI 模型 Handlebars 绑定 使用      更新时间:2023-09-26

我希望在使用手柄的Backbone应用程序中实现UI绑定。我举了一个简单的例子来演示设计模式,但我注意到它不会很好地扩展,因为每次更改模型值时都需要渲染整个模板。

有没有一种方法可以更新手把模板中的单个值,而不需要重新渲染整个模板?

HTML:

<script id="entry-template" type="text/x-handlebars-template">
    <div class="box {{#if active}} active {{/if}}">
        <h1>{{title}}</h1>
        <p>{{description}}</p>
        <button class="btn" data-class="toggleActive">Toggle Active</button>
    </div>
</script>

JS:

var TestModel = Backbone.Model.extend({
    defaults: {
        title: "Test",
        description: "This is a test description!",
        active: false
    }
});
var TestView = Backbone.View.extend({
    template: Handlebars.compile($("#entry-template").html()),
    events: {
        "click [data-class='toggleActive']": "toggleActive"
    },
    initialize: function(){
        this.model = new TestModel();
        this.render();
        this.model.on("change", this.renderUI, this);
    },
    render: function(){
        var self = this;
        $('body').html(self.$el.html(self.template(self.model.toJSON())));
    },
    renderUI: function(){
        this.$el.html(this.template(this.model.toJSON()));
    },
    toggleActive: function(){
        var isActive = this.model.get("active");
        this.model.set("active", !isActive);
    }
});
var testView = new TestView();

如果您的视图知道模板中使用元素的每个地方的选择器,您可以执行以下操作,为每个属性更改创建一个单独的处理程序,并使用您提供的选择器更新相关的HTML

var TestView = Backbone.View.extend({
    template: Handlebars.compile($("#entry-template").html()),
    events: {
        "click [data-class='toggleActive']": "toggleActive"
    },
    modelBindings: {
      // property name: CSS selector of where to update
      title: 'h1',
      description: 'p'
    },
    initialize: function(){
        this.model = new TestModel();
        this.render();
        var me = this;
        function createHandler(selector) {
            return function(model, value) {
                me.$(selector).html(value);
            }                
        }
        for (var modelProp in this.modelBindings) {
            this.model.on("change:" + modelProp, createHandler(this.modelBindings[modelProp]));
        }
    },
    render: function(){
        var self = this;
        $('body').html(self.$el.html(self.template(self.model.toJSON())));
    },
    toggleActive: function(){
        var isActive = this.model.get("active");
        this.model.set("active", !isActive);
    }
});

这只适用于您想要更新HTML的地方,而在您想要添加类的情况下则不起作用。在这种情况下,您可以使用相同的概念来添加/删除元素的属性

您可以监听模型上的特定属性更改,只更新相应的html元素。

侦听模型标题更改(this.listenTothis.on相同,但它允许侦听器在调用this.stopListening时解除绑定)。

this.listenTo(this.model, 'change:title', this.updateTitle);

然后创建updateTitle处理程序。

updateTitle: function(model, value, options)
{
    // this.$ === this.$el.find
    this.$('h1').text(value);
}