单个型号不显示路由器

时间:2017-04-26 13:39:19

标签: javascript backbone.js

我无法理解如何展示单品。当我想显示产品页面(模型视图 - 在productPageShow中的app.ProductItemView)时,我得到“未捕获的TypeError:无法在child.productPageShow(some.js:58)中找到未定义的属性'获取'>> this.prod = this.prodList.get(id);

这是我的代码:

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

app.ProductList = Backbone.Collection.extend({
    model: app.Product,
    url: 'php/listProducts.php'
});

// Views
app.ProductListView = Backbone.View.extend({
    el: '#product-list',
    initialize: function() {
        this.collection = new app.ProductList();
        this.collection.fetch({ reset: true });
        this.render();
        this.listenTo(this.collection, 'reset', this.render);
    },

    render: function() {
        this.collection.each(function(item) {
            this.renderProduct(item);
        }, this);
    },

    renderProduct: function(item) {
        app.productView = new app.ProductView({
            model: item
        });
        this.$el.append(app.productView.render().el);
    }
});

app.ProductItemView = Backbone.View.extend({
    tagName: 'div',
    template: _.template($('#productPage').html()),

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

app.ProductView = Backbone.View.extend({
    tagName: 'div',
    template: _.template($('#productTemplate').html()),

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

// Router
app.Router = Backbone.Router.extend({
    routes: {
        "list": 'list',
        "product/:id": "productPageShow"
    },

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

    list: function() {
        this.prodList = new app.ProductList();
        this.productListView = new app.ProductListView({ model: this.prodList });
        this.prodList.fetch();
        this.$content.html(app.productListView.el);
    },

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

$(function() {
    new app.Router();
    Backbone.history.start();
});

1 个答案:

答案 0 :(得分:0)

代码存在一些概念性问题,但没有涉及太多细节,路由器中发生了很多不属于那里的事情,但对于(当前)非复杂的应用程序而言#&# 39;易于管理。

我会专注于app.Router文件,因为这很可能是你问题的罪魁祸首。

routes: {
    "list": 'list',
    "product/:id": "productPageShow"
}

让我们从基础开始,当您在Backbone路由器(或其他框架中的任何其他路由器)中定义路由列表时,您为路由提供一个密钥,该密钥将对应于路由器将在URL中的某些内容。识别并调用回调方法。

如果您将浏览器导航到:

http://your-url#list

Backbone将调用list回调

类似地:

http://your-url#product/1

Backbone将调用productPageShow回调

要知道:只能呼叫一个路由回调!第一次Backbone路由器找到匹配的路由时,它会调用该回调并跳过所有其他回路。

在您的代码中,您依赖于this.prodList将存在于productPageShow方法中的事实,但这只会在您首先转到list路由然后转到{{1路线。

在路由器的product/{id}回调中,您在ProductListView实例上设置了list,但model既不是用户,也不是{{1}因为modelmodel

此外,您需要知道this.productList是异步操作,并且您没有使用任何回调来保证您在需要时拥有数据(除了依赖重置'事件)。

所以这将是我尝试使其可行:

Backbone.Collection

因此,如果在没有完整画面的情况下在黑暗中进行一些拍摄,则会发生变化:

  • fetch不再实例化在// Models var app = app || {}; app.Product = Backbone.Model.extend({ defaults: { coverImage: 'img/placeholder.png', id: '1', name: 'Unknown', price: '100' } }); app.ProductList = Backbone.Collection.extend({ model: app.Product, url: 'php/listProducts.php' }); // Views app.ProductListView = Backbone.View.extend({ el: '#product-list', initialize: function() { this.render(); this.listenTo(this.collection, 'reset', this.render); }, render: function() { this.collection.each(function(item) { this.renderProduct(item); }, this); }, renderProduct: function(item) { app.productView = new app.ProductView({ model: item }); this.$el.append(app.productView.render().el); } }); app.ProductItemView = Backbone.View.extend({ tagName: 'div', template: _.template($('#productPage').html()), render: function(eventName) { $(this.el).html(this.template(this.model.toJSON())); return this; } }); app.ProductView = Backbone.View.extend({ tagName: 'div', template: _.template($('#productTemplate').html()), render: function() { this.$el.html(this.template(this.model.attributes)); return this; } }); // Router app.Router = Backbone.Router.extend({ routes: { "": "list", "product/:id": "productPageShow" }, initialize: function() { this.$content = $("#product-list"); }, list: function() { this.prodList = new app.ProductList(); this.productListView = new app.ProductListView({ collection: this.prodList }); this.prodList.fetch({reset:true}); this.$content.html(app.productListView.el); }, productPageShow: function(id) { try { this.prod = this.prodList.get(id); this.prodItView = new app.ProductItemView({ model: this.prod }); this.$content.html(this.prodItView.el); } catch (e) { // Navigate back to '' route that will show the list app.Router.navigate("", {trigger:'true'}) } } }); $(function() { app.Router = new app.Router(); Backbone.history.start(); });
  • ProductListView回调中完成的ProductList集合
  • 更改了'列表中的路线'到'',这将保证列表立即显示
  • 如果list中没有可用的产品数据,请导航回Router