我的 backbone 示例不工作并且 this.el.html 不是一个函数

my backbone sample is not working and giving with this.el.html is not a function

我是 backbone 的新蜜蜂,我正在尝试以下示例

http://jsfiddle.net/naveencgr/L3orucjm/

加载时我得到 this.el.html 不是一个函数,让我知道它的原因是什么。

HTML:

<div id="container"></div>
<script type="text/template" id="template">
<input type="text" name="Name" id="Name"></input>
<input type="button" name="Add" id="Add" value="Add"></input>

<div id="list"></div>
</script>

JavaScript:

NameModel = Backbone.Model.extend({


});
var nameModel = new NameModel();
nameModel.set('name','test');
alert(nameModel.get('name'));
NameView = Backbone.View.extend({
    tagName:"li",
    render: function(){
        var template=_.template("<%=name%>", nameModel.toJSON());
       return template;
    }
});
var nameView = new NameView();
NameViewList = Backbone.View.extend({
    initialize: function(){
        this.render();
    },
    render: function(){
        var template = _.template($("#template").html(), {});
        this.el.html(template);
    },
    events : {
        "click input#Add" :"addName",
    },
    addName : function() {
        var name = $("#Name").val();
        if (name.trim().length > 0) {
           //nameModel.set("name", name);
            $("#list").append(nameView.render());
        }
    }
});
var nameViewList = new NameViewList({el : $("div#container")});

您的代码中有很多错误。你知道其中一个,但不知道其他人。

你知道的是:

this.el.html(template);

视图的 el is just a DOM node and that doesn't have an html function. The html function you're trying to use is part of jQuery so you'd want to call it on this.$el(这只是 $(this.el) 的缓存版本):

this.$el.html(template);

其他问题:

  1. 你的 fiddle 到处都不见了 var;不要说:

    NameModel = ...
    

    说:

    var NameModel
    

    避免意外的全局变量。

  2. 你的NameView很奇怪。它有 tagName: 'li',所以大概它应该创建列表元素,但是 render 对视图的 el 没有任何作用,它只是 return 一个 [=107= 的字符串] 最终在 <div> 内。 <div> 应该是 <ul>:

    <ul id="list"></ul>
    

    A render 函数通常填充视图的 el 并且为了允许链接,returns this:

    render: function() {
        var template = _.template('<%= name %>');
        this.$el.html(template(nameModel.toJSON()));
        return this;
    }
    
  3. 您错误地使用了 Underscore 的 _.template。你曾经可以说:

    var h = _.template(template_source, data);
    

    编译模板并一步填写,但是as of Underscore 1.7_.template的第二个参数是一个选项对象。现在您需要分步编译和填写模板:

    var t = _.template(template_source);
    var h = t(data);
    

    您会在上面的 render 中看到此更改。

  4. 您使用 NameView 的方式很奇怪。显然你正在尝试使用一个 NameView 来处理多个名称,这将适用于你奇怪的 NameView#render 实现但是一旦 NameView 有任何事情要做或一旦 NameView 已更新(如上)以更常规。您应该为要显示的每个名称创建一个 NameView,并且每个 NameView 都应该有自己的 NameModel 作为其 model 属性。这将使 NameView#render 看起来像:

    render: function() {
        var template = _.template('<%= name %>');
        this.$el.html(template(this.model.toJSON()));
        return this;
    }
    

    NameViewList#addName 看起来像:

    addName: function() {
        var name = this.$("#Name").val();
        if(name.trim().length > 0) {
            var nameView = new NameView({
                model: new NameModel({ name: name })
            });
            this.$('#list').append(nameView.render().el);
        }
    }
    

    你会注意到我们正在使用 NameView#render 的新 return 值,这个 x.append(v.render().el) 模式在 Backbone 中非常常见和惯用,所以它是一个好习惯。您还应该注意到,通过使用视图的 this.$ 函数,搜索 #list 现在仅限于视图的 elthis.$('#list') 等同于 this.$el.find('#list'),以这种方式做事可以帮助您保持观点独立。

    在现实生活中,您可能会将 new NameModel({ name: name }) 实例放在某个集合中,该集合上的事件会触发新 NameViews 的创建。

将所有这些应用到您的 fiddle 中,您将得到这个更实用且更惯用的版本:

http://jsfiddle.net/ambiguous/8x0ma9qo/