【问题标题】:Creating backbone views with models from other views使用来自其他视图的模型创建主干视图
【发布时间】:2013-04-17 19:47:05
【问题描述】:

背景:

我正在对一个使用带有 Handlebars 的主干.js 作为模板引擎的应用程序进行更改。在更改事件触发后,我需要创建附加到当前 DOM 结构的 html,这基本上只是模型中包含的信息的吐出。此更改需要适应已建立的应用程序结构。

问题:

我创建了一个使用 Handlebars 模板和模型来创建 html 的新视图。然后我实例化该视图并调用渲染函数并使用 JQuery 附加输出。我注意到的是,当呈现 html 时,传入的模型是因为 $el 上的属性而不是填充模板(就像我认为应该的那样)。

我正在更改的视图:

$.hart.TestView = Backbone.View.extend({
    tagName: "li",
    template: Handlebars.compile($('#templateOne').html()),
    initialize: function () {
        this.model.on('change', function () {
            this.createMoreInfoHtml();
        }, this);
    },
    selectSomething: function () {
        this.$el.removeClass('policies');

        this.createMoreInfoHtml(); //function created for new view stuff
    },
    createMoreInfoHtml: function () {
        var id = this.$el.attr('data-id', this.model.get("ID"));
        $('.info').each(function () {
            if ($(this).parent().attr('data-id') == id 
                $(this).remove();
        });

        var view = new $.hart.NewView(this.model, Handlebars.compile($("#NewTemplate").html()));
        $('h1', this.$el).after(view.render().el);
    },
    render: function () {
        ... //render logic
    }
});

我创建的视图:

$.hart.NewView = Backbone.View.extend({
        initialize: function (model, template) {
            this.model = model;
            this.template = template;
        },
        render: function () {
            this.$el.html(this.template({ info: this.model }));
            this.$el.addClass('.info');
            return this;
        }
    });

Json 是模型:

{
        "PetName":"Asdfasdf", 
        "DateOfBirth":"3/11/2011 12:00:00 AM",      
        "IsSpayNeutered":false, 
        "Sex":"F", 
        "SpeciesID":2, 
        "ID":"ac8a42d2-7fa7-e211-8ef8-000c2964b571"
    }

模板

<script id="NewTemplate" type="text/html">
        <span>Pet Name: </span>
        <span>{{this.PetName}}</span>
    </script>

那么现在的问题是:我做错了什么?为什么模型的属性被创建为 $el 上的属性而不是填充模板?有人可以指导我如何获得我正在寻找的结果吗?

【问题讨论】:

  • 您是否忘记在您的模型上调用toJSON()?,例如this.template(this.model.toJSON())
  • @Jack,好吧,我没有那样做。这样做会填充值,但我仍然遇到问题,它还会在包含这些值的元素上创建属性。这绝对是一个开始!谢谢

标签: backbone.js handlebars.js


【解决方案1】:

让我们跳过杰克注意到的问题。
您创建视图的方式是错误的。当您在初始化函数中获得预期的参数时,它可能会起作用,但它具有您看不到的意外行为。查看 View 的构造函数:

var View = Backbone.View = function(options) {
  this.cid = _.uniqueId('view');
  this._configure(options || {});

现在让我们看看这个_configure方法:

_configure: function(options) {
  if (this.options) options = _.extend({}, _.result(this, 'options'), options);
  _.extend(this, _.pick(options, viewOptions));

当然……

var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];

好的,我们在这里...基本上,当将模型作为options 参数传递时,您传递的是一个带有attributes 键(模型的属性)的对象。但是这个attributes 键也在视图中用于将属性绑定到它的元素!因此,您注意到的行为。

现在,另一个错误的事情。每次创建新函数时都在编译模板,但也不将其用作单例。将您的模板放入视图中:

$.hart.NewView = Backbone.View.extend({
  template: Handlebars.compile($("#NewTemplate").html(),

并更改视图的创建以使整个工作正常:

new $.hart.NewView({model: this.model});

哦,摆脱这种无用的initialize 方法。你只是在做 Backbone 已经在做的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 2013-09-28
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多