【问题标题】:setting model content in back bone using underscore external template使用下划线外部模板在主干中设置模型内容
【发布时间】:2014-04-29 12:30:42
【问题描述】:

这是我的主干代码,我在其中使用下划线模板,现在工作正常,我正在尝试将该模板设为外部并从那里加载

这是我的示例主干代码

骨干应用

<div class="list"></div>

<script id="personTemplate" type="text/template">
    <strong><%= name %></strong> (<%= age %>) - <%= occupation %>
</script>
<script type="text/javascript">
var Person = Backbone.Model.extend({
    defaults: {
        name: 'Guest User',
        age: 23,
        occupation: 'worker'
    }
});

var PersonView = Backbone.View.extend({
   tagName: 'li',

    template: _.template( $('#personTemplate').html()),

    initialize: function(){
        this.render();
    },

    render: function(){
        this.$el.html( this.template(this.model.toJSON()));
    }
});
var person = new Person;  // a person object created...
//person.set('name', 'abhi');
var personView = new PersonView({ model: person });
personView.el   // ---->; You can call this method and it will display the view..
$(document.body).html(personView.el);
</script>
</body>
</html> 

真正需要的是我将这个模板&lt;strong&gt;&lt;%= name %&gt;&lt;/strong&gt; (&lt;%= age %&gt;) - &lt;%= occupation %&gt; 放在一个外部文件中。我不太了解它的扩展名,我认为它可以是一个 html 文件并从那里加载模板,我对其进行了研究并找到了一些示例代码并尝试了类似的东西

<script type="text/javascript">
_.mixin({templateFromUrl: function (url, data, settings) {
    var templateHtml = "";
    this.cache = this.cache || {};

    if (this.cache[url]) {
        templateHtml = this.cache[url];
        alert(templateHtml);
    } else {
        $.ajax({
            url: url,
            method: "GET",
            async: false,
            success: function(data) {
                templateHtml = data;
                alert(templateHtml);
            }
        });

        this.cache[url] = templateHtml;
    }

    return _.template(templateHtml, data, settings);
}});
var Person = Backbone.Model.extend({
    defaults: {
        name: 'Guest User',
        age: 23,
        occupation: 'worker'
    }
});

var PersonView = Backbone.View.extend({
   tagName: 'li',

   template:_.templateFromUrl("templatefile1.html", {"name": "value","age":10}) ,
   // template:_.templateFromUrl("templatefile1.html", this.model.toJSON()) ,
  //template: _.template( $('#personTemplate').html()),
    initialize: function(){
        this.render();
    },

    render: function(){
    alert(this.template);
        this.$el.html( this.template);
    }
});
var person = new Person;  // a person object created...
//person.set('name', 'abhi');
var personView = new PersonView({ model: person });
personView.el   // ---->; You can call this method and it will display the view..
$(document.body).html(personView.el);
</script>

但是当我像这样调用模板时template:_.templateFromUrl("templatefile1.html", {"name": "value","age":10}) , 这是工作 但是当我尝试像这样将传递模型传递给该模板时

template:_.templateFromUrl("templatefile1.html", this.model.toJSON())

我遇到了像

这样的异常
Uncaught TypeError: Cannot read property 'toJSON' of undefined 

我该如何解决这个问题

【问题讨论】:

  • 小心$(document.body).html(personView.el);,看起来您将&lt;script&gt;s 存储在&lt;body&gt; 中,而$('body').html(...) 在添加新内容之前会清除&lt;body&gt;
  • @mu 太短了 1 感谢您的想法,这只是一个示例代码
  • @mu 太短了,我试过了,但是还是不行,能否提供代码?
  • 您具体尝试了什么?具体出了什么问题?

标签: javascript templates backbone.js underscore.js


【解决方案1】:

你说的是这样的:

var PersonView = Backbone.View.extend({
    //...
    template: _.templateFromUrl("templatefile1.html", this.model.toJSON()),
    //...
});

你认为this 在这种情况下是什么?它肯定不会是您的视图的实例,因为尚未创建任何实例。 this 将是 window 在级别和 window 不会有一个有用的 model 属性。您需要推迟该调用,直到使用 model 属性创建视图实例。

您可以将template 设为方法:

template: function() {
    return _.templateFromUrl('templatefile1.html', this.model.toJSON());
}

然后在适当的时候调用它:

render: function(){
    this.$el.html(this.template());
    return this; // <----- Standard practise so you can x.append(v.render().el)
}

我建议不要将async:false$.ajax 一起使用,但这对人们来说是一件讨厌的事情。相反,您应该向templateFromUrl 提供一个回调函数,当模板从服务器进入时它可以调用该函数。

如果您要经常做这种事情,那么您可以将template 函数添加到基本视图:

var BaseView = Backbone.View.extend({
    template: function() {
        // This assumes that you have exactly one of `this.model` and
        // `this.collection`, you can do other things here if that doesn't
        // work in your world.
        var data_source = this.model || this.collection;
        return _.templateFromUrl(this.template_name, data_source.toJSON());
    }
});

然后使用它你的PersonView:

var PersonView = BaseView.extend({
    template_name: 'templatefile1.html',
    render: function() {
        this.$el.html(this.template());
        return this;
    },
    //...
});

【讨论】:

  • -如何使 templateFromUrl 成为回调函数,能否提供代码?
  • 只需向templateFromUrl 添加另一个参数来保存回调,然后在AJAX success 处理程序中调用该回调。如果模板已经在缓存中,则直接调用回调。
【解决方案2】:

您需要使模型可重用,并定义一个url:

 var PersonModel = Backbone.Model.extend({
    defaults: {
        name: 'Untitled',
        age: 0,
        occupation: null,
    },
    url: "/somefile.json"
});

为视图内的模型更改创建监听器,并获取模型:

    initialize: function(options){
        this.listenTo(this.model, "change", this.render);
        this.model.fetch();
    }

创建一个新模型,然后将其传递给新视图:

var person = new PersonModel();
var personView = new PersonView({ model: person });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多