2017-04-26 62 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