2017-04-26 64 views
0

我无法理解如何显示单个产品。当我想显示产品页面时(模型视图 - productPageShow中的app.ProductItemView),我得到“Uncaught TypeError:无法读取child.productPageShow(some.js:58)undefined的属性'get'”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(); 
}); 
+0

缩进没有可用的产品数据4个空格代码块,保持集中的问题的描述内容,在适当的英语写,包括[ mcve],强调**最小**。 –

+0

Emile感谢您的评论。但我真的认为有一个最小的信息来了解我的问题 – Vovix

+0

什么是错误?发生了什么?产品列表是否正确显示? –

回答

0

没有与代码中的一些概念上的问题,并没有涉及到太多的细节,有很多的东西不属于那里的路由器发生,但对于可管理的(当前)非复杂应用程序。

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

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

让我们从基础开始,当你定义的骨干路由器的路由列表(或其他框架中的任何其他路由器),你给的路线,将对应的东西在URL中的一个关键路由器将识别并调用回调方法。

如果您浏览的浏览器:

http://your-url#list 

骨干将调用list回调

同理:

http://your-url#product/1 

骨干将调用productPageShow回调

是要知道: 只有一个路由回拨可以被呼叫!骨干路由器第一次找到匹配的路由时,它将调用该回调并跳过所有其他路由。

在你的代码要依靠事实this.prodList将在productPageShow方法存在,但如果你先去list路线,然后product/{id}路由才会发生。

另一件事..在路由器上你list回调您在ProductListView实例..设置modelmodel既不是用户,也不是model因为this.productListBackbone.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
  • 将路由从'list'更改为'',这将保证列表被立即
  • 所示的情况下有在productPageShow导航回到list
+0

还有很多可以改进的地方,而且你们的方向是正确的,但是尝试抓住并不是一个改进**。 –

+0

感谢您的回答马里奥。我会尝试在骨干研究中使用这些信息。 – Vovix

+0

@EmileBergeron ..我知道还有其他的东西需要改进,我的版本可能会完全不同于这个版本,但我只是想帮助解决即时问题而不改变原有代码。我通常实践渐进式改进,如果尝试解决问题,这是一个新的改进的新起点,我没有看到任何错误:) – Mario