骨干更改事件未触发

时间:2012-03-16 11:09:45

标签: javascript backbone.js backbone-events

我正在学习Backbone并在一个地方敲击。我想在页面加载时加载模型。所以我有以下代码。

<html>
<head>
    <script src="js/jquery.min.js"></script>
    <script src="js/underscore-min.js"></script>
    <script src="js/backbone-min.js"></script>
    <script src="js/json2.js"></script>
</head>
<body>
    <h1></h1>
    <div id="poview"></div>
    <script id="poTemplate" type="text/template">
        <td><%= Ponumber %></td>
        <td><%= Posuppliername %></td>
        <td><%= Postatusname %></td>
        <td><%= Podate %></td>
        <td><%= DispOrderTotal %></td>
    </script>
    <script type="text/javascript">
        (function($) {
            var PO = Backbone.Model.extend()

            var POList = Backbone.Collection.extend({
                url: 'po.json',
                model: PO,
                parse: function(response) {
                    console.log(response.PurchaseOrder)
                    return response.PurchaseOrder
                }
            })

            var POView = Backbone.View.extend({
                tagName: 'tr',
                template: $('#poTemplate').html(),
                initialize: function() {
                    _.bindAll(this, 'render')
                    this.model.bind('change', this.render)
                },
                events: {
                    'click': 'click'
                },
                render: function() {
                    console.log('po render')
                    var tmpl = _.template(this.template)
                    $(this.el).html(tmpl(this.model.toJSON()))
                    return this;
                },
                click: function() {
                    console.log('clicked....')
                }
            })

            var POListView = Backbone.View.extend({
                el: $('#poview'),
                initialize: function() {
                    _.bindAll(this, 'render', 'appendPO')
                    this.collection = new POList()
                    this.collection.bind('change', this.render, this)
                    this.collection.bind('add', this.render, this)
                    this.collection.fetch({add:true})
                },
                render: function() {
                    var self = this;
                    console.log(this.collection.models)
                    this.collection.each(function(po) {
                        self.appendPO(po)
                    }, this)
                },
                appendPO: function(po) {
                    var poView = new POView({
                        model: po
                    });
                    console.log(po)
                    $(this.el).append(poView.render().el)               
                }
            });

            var poListView = new POListView()

        })(jQuery)
    </script>
</body>
</html>

以下是来自服务器的json响应

{
    "@totalCount": "1134",
    "PurchaseOrder": [
        {
            "ID": "689600",
            "Ponumber": "K037412201",
            "Poname": "",
            "Podate": "2011-12-26T10:03:24.000+05:30",
            "Posuppliername": "XYZ UPS Supplier",
            "Postatusname": "Approved - Supplier Received",
            "DispOrderTotal": "$1.99"
        },
        {
            "ID": "689601",
            "Ponumber": "K037412202",
            "Poname": "",
            "Podate": "2011-12-26T10:03:24.000+05:30",
            "Posuppliername": "ABC UPS Supplier",
            "Postatusname": "Approved - Supplier Received",
            "DispOrderTotal": "$1.99"
        }
    ]
}

但是当加载页面时,不会触发POListView上的渲染方法。这段代码有什么问题?

修改

jQuery(function($){
  ...
});

如果我也使用上述惯例,则不起作用。

工作示例 请参阅@JayC的答案

<html>
<head>
    <script src="js/jquery.min.js"></script>
    <script src="js/underscore.js"></script>
    <script src="js/backbone.js"></script>
    <script src="js/json2.js"></script>
</head>
<body>
    <h1></h1>
    <div id="poview"></div>
    <script id="poTemplate" type="text/template">
        <td><%= Ponumber %></td>
        <td><%= Posuppliername %></td>
        <td><%= Postatusname %></td>
        <td><%= Podate %></td>
        <td><%= DispOrderTotal %></td>
    </script>
    <script type="text/javascript">

        jQuery(function($) {
            var PO = Backbone.Model.extend({
                idAttribute: 'ID'
            })

            var POList = Backbone.Collection.extend({
                url: 'po.json',
                model: PO,
                parse: function(response) {
                    console.log('parse')
                    return response.PurchaseOrder
                }
            })

            var POView = Backbone.View.extend({
                tagName: 'tr',
                template: $('#poTemplate').html(),
                initialize: function() {
                    _.bindAll(this, 'render', 'click')
                },
                events: {
                    'click': 'click'
                },
                render: function() {
                    var tmpl = _.template(this.template)
                    $(this.el).html(tmpl(this.model.toJSON()))
                    return this;
                },
                click: function() {
                    console.log('clicked.... ' + this.model.id)
                }
            })

            var POListView = Backbone.View.extend({
                el: $('#poview'),
                initialize: function() {
                    _.bindAll(this, 'render', 'appendPO')
                    this.collection = new POList()
                    this.collection.bind('reset', this.render, this)
                    this.collection.fetch()
                },
                render: function() {
                    var self = this;
                    console.log(this.collection.models)
                    this.collection.each(function(po) {
                        self.appendPO(po)
                    }, this)
                },
                appendPO: function(po) {
                    var poView = new POView({
                        model: po
                    });
                    $(this.el).append(poView.render().el)               
                }
            });

            var poListView = new POListView()

        });
    </script>
</body>
</html>

2 个答案:

答案 0 :(得分:5)

我没有看到对您的收藏的reset事件的绑定。 Backbone.js文档现在有一个FAQ解释事件(最后!),你可以从中看到 当集合的全部内容被替换时,reset事件将触发。关于集合,这就是fetch通常所做的事情。

答案 1 :(得分:0)

你写了这个,当DOM尚未准备好/可用时立即执行该功能:

(function($){
  ...
})(jQuery);

但是你可能想写这个(见http://api.jquery.com/jQuery/#jQuery3),这会延迟函数,直到文档准备好被操作(附上你的观点等):

jQuery(function($){
  ...
});

当然,只有实际的初始化调用应该包含在jQuery()中,其他部分可以保留在普通的闭包中。