Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 模型视图仅显示默认值_Javascript_Backbone.js - Fatal编程技术网

Javascript 模型视图仅显示默认值

Javascript 模型视图仅显示默认值,javascript,backbone.js,Javascript,Backbone.js,我的backbone.js代码怎么了? 当产品页面加载时,只显示模型的默认值…尽管在控制台中我看到了正确的数据… 这是我的模型: var app = app || {}; app.Product = Backbone.Model.extend({ defaults: { coverImage: 'img/placeholder.png', id: null, name: 'Unknown', price: '100'

我的backbone.js代码怎么了?
当产品页面加载时,只显示模型的默认值…
尽管在控制台中我看到了正确的数据…

这是我的模型:

var app = app || {};
app.Product = Backbone.Model.extend({
    defaults: {
        coverImage: 'img/placeholder.png',
        id: null,
        name: 'Unknown',
        price: '100'
    }
});
收藏:

var app = app || {};
app.ProductList = Backbone.Collection.extend({
    model: app.Product,
    url: 'php/listProducts.php'
});
我的看法是:

var app = app || {};
app.ProductItemView = Backbone.View.extend({
    template: _.template($('#productPage').html()), 

    initialize: function(options) {
        var id = options.id;
        this.model = new app.Product();
        this.collection = new app.ProductList();
        this.collection.fetch({
            success: function(collection){
                console.log(collection.toJSON());
                console.log('Collection models: ', collection.models[id-1]);
                this.model = collection.models[id-1];
                console.log('This model: ', this.model);
            }
        });

        this.render();
    },

    render: function () { 
        this.$el.html( this.template( this.model.attributes ) );
        return this; 
    }


});
路由器:

var app = app || {};
app.Router = Backbone.Router.extend({
    routes: {
        "product/:id": "productPageShow"
    },

    initialize: function () {
        this.$content = $("#product-list");
    },

    productPageShow: function(id) {
        app.prodItView = new app.ProductItemView({ id: id });
        this.$content.html(app.prodItView.el);
    }

});

$(function() {
    new app.Router();
    Backbone.history.start();
});
我的模板:

<div class="container">    
    <div id="product-list"></div>
</div>

<script id="productPage" type="text/template">
    <div>
        <img src="<%= coverImage %>" class="img-responsive" style="width:100%" alt="<%= name %>">
    </div>
    <div>
        <h2><%= name %></h2>
    </div>
    <div>
        <h3><%= price %></h3>
    </div>
</script>

“class=“img responsive”style=“width:100%”alt=“”>
控制台映像:


之所以发生这种情况,是因为“fetch”是一个异步操作,因此在调用
fetch()
success()
回调之前,始终会调用
render()

如果需要,请提供一些额外资源:

要在代码上直观地解释
initialize
方法中的执行顺序:

var app = app || {};
app.ProductItemView = Backbone.View.extend({
    template: _.template($('#productPage').html()), 

    initialize: function(options) {
        // 1
        var id = options.id;
        // 2
        this.model = new app.Product();
        // 3
        this.collection = new app.ProductList();
        // 4 - fetch is only called and ajax request is sent to your backend.
        //     success callback is still not called
        this.collection.fetch({
            success: function(collection) {
                // 6 - when you get the data from the server the callback is called
                //     but the page is already rendered at this time
                console.log(collection.toJSON());
                console.log('Collection models: ', collection.models[id-1]);
                this.model = collection.models[id-1];
                console.log('This model: ', this.model);
            }
        });

        // 5
        this.render();
    },

    render: function () { 
        this.$el.html( this.template( this.model.attributes ) );
        return this; 
    }
});
修复应该相当简单,只需在成功回调的底部调用render方法并绑定到视图的正确上下文:

var app = app || {};
app.ProductItemView = Backbone.View.extend({
    template: _.template($('#productPage').html()), 

    initialize: function(options) {
        var id = options.id;
        this.model = new app.Product();
        this.collection = new app.ProductList();
        this.collection.fetch({
            success: _.bind(function(collection) {
                console.log(collection.toJSON());
                console.log('Collection models: ', collection.models[id-1]);
                this.model = collection.models[id-1];
                console.log('This model: ', this.model);

                // Moved render call here
                this.render();
            }, this)
        });

    },

    render: function () { 
        this.$el.html( this.template( this.model.attributes ) );
        return this; 
    }
});

另外,正如一般建议一样..不要直接从集合中选择模型..对集合使用提供的
get
方法并传递所需的模型
id

马里奥非常感谢你的回答和建议!它很有效。
.fetch
函数可以使用一个
上下文
选项,避免使用
.bind
@EmileBergeron-这确实是真的。在我多年的主干网工作中,我都没有注意到这一点。文档中没有,我只是在源代码中确认了它。它这很奇怪,因为
上下文
通常作为最后一个参数传递,尽管如此,非常好的提示!谢谢:)的可能重复