0

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

 <!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>
4

1 回答 1

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 带有内联“文本”脚本。我不推荐任何方法来处理它,这就是我在这里所做的。

于 2013-07-03T23:39:13.710 回答