Backbone JS视图呈现不显示

时间:2015-01-27 08:08:15

标签: javascript jquery backbone.js

在下面的代码中,无法呈现'TodoList'。似乎需要花费时间,因此仅在显示“0”和<div id=​"demo">​</div>​之前。

并且我不确定为什么'3'和'Descriptions'稍后会显示出来。我只需要在页面中显示“Descriptions List”。我能够从服务器获取数据,但不知何故无法在数据到达时立即显示。请告诉我在下面的代码中需要做哪些更改?

<html>
<head>
<link rel="stylesheet"
    href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.1/css/bootstrap.min.css">
</head>

<body>

<div id="demo"></div>

<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>

<script type="text/javascript">

var TodoItem = Backbone.Model.extend({
    urlRoot: 'api',
})

var TodoCollection = Backbone.Collection.extend({
    model: TodoItem,
    url: 'api/todos'
})

var TodoView = Backbone.View.extend({
    template: _.template('<h3> ' +'<input type=checkbox ' +'<% if(status === "complete") print("checked") %>/>' +' <%= description %></h3>'),
    render: function(){
        this.$el.html(this.template(this.model.toJSON()))
    }

})

var TodoListView = Backbone.View.extend({
    initialize: function(){
        this.listenTo(this.collection,'reset',this.render)
        this.collection.fetch({reset:true})
    },
    render: function(){
        console.log(this.collection.length)
        this.collection.forEach(this.addOne,this)
    },
    addOne: function(todoItem){
        console.log(todoItem.get('description'))
        var todoView = new TodoView({model: todoItem})
        this.$el.append(todoView.render())
    }

})


var todoItem = new TodoItem()
var todoList = new TodoCollection()

var todoListView = new TodoListView({el: '#demo', collection: todoList})

todoListView.render()

console.log(todoListView.el)


</script>

</body>

</html>

这是我获得的CONSOLE输出:

0 
<div id=​"demo">​</div>​     
3 
pick up cookies
Milk 
Cookies 

2 个答案:

答案 0 :(得分:1)

对于初学者,您可能希望从提取中取出{reset:true}。 无论如何,fetch会自动清除模型/集合。

请在命令末尾使用分号,不使用它们会让浏览器解释分号的位置。这需要时间并且容易出错(浏览器可能只是把它放在你认为不会的地方)。

如果这不起作用,您可能希望将fetch添加到渲染中,执行此操作:

render: function(){

    var that = this;

    this.collection.fetch().done(function(data) {

        console.log(that.collection.length);
        that.collection.forEach(that.addOne,that);

    });

},

也可能有用,但你需要对此进行测试,我个人总是使用上面的那个:

render: function(){

    this.collection.fetch().done(function(data) {

        console.log(this.collection.length);
        this.collection.forEach(this.addOne,this);

    }, this);

},

答案 1 :(得分:0)

我不知道为什么&#39; 3&#39;和&#39;描述&#39;稍后显示 - 因为它是异步Ajax请求的结果。

现在,尝试更改您的代码(观看评论):

var TodoView = Backbone.View.extend({
    template: _.template('<h3> ' +'<input type=checkbox ' +'<% if(status === "complete") print("checked") %>/>' +' <%= description %></h3>'),
    clearItem : function(){
         this.$el.find("h3").remove();
    },
    render: function(){
        //all DOM manipulation in view
        this.$el.append(this.template(this.model.attributes));
        return this;
    }

})

var TodoListView = Backbone.View.extend({
    initialize: function(){
        // split "reset" event and "add" event
        this.listenTo(this.collection,'reset',this.removeAll);
        this.listenTo(this.collection,'add',this.addOne);
        this.collection.fetch({reset:true});
    },

    removeAll : function(){
        //method to remove all element from view
        //your problem is that this event will fire before ajax request done
        console.log("reset!");
        var todoView = new TodoView();
        todoView.clearItem();
    },

    addOne: function(todoItem){
        //fire when a model in the collection change (automatic after fetch result) for each model.
        console.log("add ITEM:",todoItem);
        var todoView = new TodoView({model: todoItem})
        todoView.render();
    }

});

注意:删除代码中的todoListView.render()

抱歉,我的英语太差了。我没有时间更好地解释。试试我的代码是否正常工作