为什么骨干视图没有得到渲染

时间:2013-07-03 17:41:32

标签: backbone.js

下面是我用于简单任务添加的代码,视图没有得到渲染,我无法找到错误,

 <!doctype html>
<html lang="en">
<head>

    <title>Calculator</title>
    <link rel="stylesheet" href="styles/bootstrap/css/bootstrap.min.css">
     <script src="js/libs/jquery-1.9.1.min.js"></script>
    <script src="js/libs/underscore-min.js"></script>
    <script src="js/libs/backbone-min.js"></script>
    <script type="text/template" id="display-template">
        <div class="row">
            <div class="span4">
                <%=content%>
            </div>
        </div>
    </script>
<script language="javascript">
var cdate;
var tasks={};

var app = app || {};

// App view responsible for rendering app
app.TaskView = Backbone.View.extend({

    el: $('#tasks'),

    template: _.template($('#display-template').html()),

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

    render: function () {
        console.log("render called");
        console.log(this.template());
        this.$el.html(this.template());
    }
});
app.task = Backbone.Model.extend({

    defaults:{
        content:null
    }
});
app.bUsers = Backbone.Collection.extend({ 
    model : app.task,
    initialize: function(models, args) {
       this.bind('add', this.renderone);
       this.bind('remove', this.destroy); },
    renderone:function(user){
        console.log(user);
        var view = new app.TaskView({model: user});
    },
   destroy:function(user){
        $(user.view.el).remove();
    }
});

app.Users = new app.bUsers();

$(document).ready(function() {



    cdate=new Date();
    $("#cdate").html(new Date());
    $("#pre").click(function(){
        cdate=new Date(cdate.getTime()-(1*24*3600*1000));
        $("#cdate").html(cdate);

    });
    $("#next").click(function(){
        cdate=new Date(cdate.getTime()+(1*24*3600*1000));
        $("#cdate").html(cdate);

    });
    $("#submit").click(function(){
        if(tasks[cdate]==undefined) tasks[cdate]=[];
        tasks[cdate].push($("#task").val());
        // app.appView = new app.TaskView({
            // model: new app.task({"content":$("#task").val()})
        // });
        var data ={"content":$("#task").val()}; 
        app.Users.add(data);


    });


});

</script>

</head>
<body>

<a id="pre" href="#">Prev</a>
<div id="cdate"></div>
<a id="next" href="#">Next</a>
<input type="text" id="task" ></input>
<input type="button" value="submit" id="submit" ></input>
<div id="tasks"></div>
</body>

1 个答案:

答案 0 :(得分:1)

哦,你有一些问题。

要回答您的具体问题,您的视图渲染方法应该使用视图的模型实例并从this.model.toJSON()获取一些内容以获取其数据以传递给模板方法(toJSON确实返回“JSONable”对象)。

但这不是全部。

除了一些html问题,你也有风格问题。

集合通常不应该关注视图,只关注数据(*)。观点应该与馆藏和模型有关。集合通过事件绑定与视图进行通信,我看到你正在做的事情。但是,出于重用目的,您可能有多个组合视图可能希望侦听集合中的事件。通过在集合中设置事件绑定,您可以有效地限制集合仅用于一次。

视图可以做很多。当您可以编写视图代码来为您执行此操作时,没有太多理由手动添加DOM事件处理程序。

我有一段时间没有编写Backbone(不是选择!),但一般认为最好有一个专用于集合的视图,然后有一个单独的模型视图,集合视图可能会创建或根据发生的任何事件进行破坏。

这里有一些代码清理,为您提供一个起始示例:

http://jsfiddle.net/jfcox/SmPNv/

HTML:

<a id="pre" href="#">Prev</a>

<div id="cdate">&nbsp;</div>
<a id="next" href="#">Next</a>

<input type="text" id="task" />
<input type="button" value="add" id="submit" />
<div id="tasks"></div>

骨干定义:

var defs = defs || {};
//first define the data handlers
defs.Task = Backbone.Model.extend({
    defaults: function () {
        return {
            content: null,
            addDate: (new Date()).toString()
        };
    }
});
defs.Users = Backbone.Collection.extend({
    model: defs.Task
});


// App view responsible for rendering app
defs.SingleTaskView = Backbone.View.extend({
    //since we can't control where the js is loaded, go ahead and make the template inline for jsFiddle demo.
    tagName: 'div',
    template: _.template('<div class="row">  <div class="span4"><%=content%></div> <em><%=addDate%></em> <button class="remove"> remove</remove> </div>'),
    events: {
        "click button.remove": "remove"
    },
    initialize: function (opts) {
        this.model.on('change', this.render, this);
    },
    render: function () {
        console.log("render called");
        var modelBare = this.model.toJSON();
        return this.$el.html(this.template(modelBare));
    },
    remove: function () {
        //removes from local collection, does not delete on server
        //for that, you'd want `this.model.destroy`
        this.collection.remove(this.model);
        //removes this view's element.
        this.$el.remove();
    }
})

defs.TasksView = Backbone.View.extend({

    el: 'body',
    events: {
        "click #pre": "doPrevious",
            "click #next ": "doNext",
            "click #submit ": "doSubmit"
    },
    cdate: null,
    initialize: function (opts) {
        this.cdate = new Date();
        this.render();
        this.collection.on('add', this.renderone, this);
    },
    render: function () {
        $("#cdate").html(this.cdate.toString());
    },
    doPrevious: function () {
        this.cdate = new Date(this.cdate.getTime() - (1 * 24 * 3600 * 1000));
        $("#cdate").html(this.cdate.toString());

    },
    doNext: function () {
        this.cdate = new Date(this.cdate.getTime() + (1 * 24 * 3600 * 1000));
        $("#cdate").html(this.cdate.toString());
    },
    doSubmit: function () {
        var data = {
            "content": $("#task").val()
        };
        this.collection.add([data]);
    },
    renderone: function (userModel) {
        var view = new defs.SingleTaskView({
            model: userModel,
            collection: this.collection
        });
        this.$el.find('#tasks').append(view.render());
    }
});

应用程序本身。

var app = app || {};

app.users = new defs.Users();
(function ($) {
    $(document).ready(function () {
        app.usersview = new defs.TasksView({
            collection: app.users
        });

    });
})(jQuery);

(*)这是一个指导方针,当然不是绝对的规则。如果您认为某个集合可能会起到某种工作流管理器等作用,那可能会很好,但这是一个高级主题。

编辑:我将内嵌模板包含在内,部分原因是我不相信jsFiddle内联“文本”脚本。我不建议任何方式来解决这个问题,就像我在这里做的那样。