2013-04-26 15 views
8

Vì vậy, tôi bị kẹt. Tôi có Backbone.Marionette tuyệt vời để xử lý các mối quan hệ con và cha mẹ lồng nhau của tôi (làm với nó với xương sống trần là một cơn ác mộng), nhưng bây giờ tôi đang gặp vấn đề với phối cảnh lồng nhau của tôi,Backbone Marionette Nested Composite Xem

Tôi luôn nhận được Không tìm thấy itemViewContainer được chỉ định: .tab-content từ chế độ xem tổng hợp gốc - CategoryCollectionView, mặc dù itemViewContainer có sẵn trên mẫu, đây là những gì tôi đang cố gắng thực hiện, tôi có một thực đơn nhà hàng tôi cần hiện tại, vì vậy tôi có một số danh mục và trong mỗi danh mục tôi có một số mục menu, vì vậy html cuối cùng của tôi sẽ như sau:

<div id="order-summary">Order Summary Goes here</div> 
    <div id="categories-content"> 
     <ul class="nav nav-tabs" id="categories-tabs"> 
       <li><a href="#category-1">Appetizers</a></li> 
     </ul> 
     <div class="tab-content" > 
       <div class="tab-pane" id="category-1"> 
        <div class="category-title">...</div> 
        <div class="category-content">..the category items goes here.</div> 
     </div> 
    </div> 

H ere là những gì tôi có cho đến nay:

Đầu tiên các mẫu

mẫu-skeleton

<div id="order-summary"></div> 
<div id="categories-content"></div> 

mẫu menu-core

<ul class="nav nav-tabs" id="categories-tabs"></ul> 
<div class="tab-content" ></div> 

mẫu-loại

<div class="category-title"> 
    <h2><%=name%></h2> 
    <%=desc%> 
</div> 
<div class="category-content"> 
    The menu items goes here 
    <ul class="menu-items"></ul> 
</div> 

mẫu menu-item

Item <%= name%> 
<strong>Price is <%= price%></strong> 
<input type="text" value="<%= quantity %>" /> 
<a href="javascript:void()" class="add">Add</a> 

Bây giờ kịch bản

var ItemModel = Backbone.Model.extend({ 
    defaults: { 
     name: '', 
     price: 0, 
     quantity: 0 
    } 
}); 

var ItemView = Backbone.Marionette.ItemView.extend({ 
    template: '#template-menuitem', 
    modelEvents: { 
     "change": "update_quantity" 
    }, 
    ui: { 
     "quantity" : "input" 
    }, 
    events: { 
     "click .add": "addtoBasket" 
    }, 
    addtoBasket: function (e) { 
     this.model.set({"quantity": this.ui.quantity.val() }); 
    }, 
    update_quantity: function() { 
     //@todo should we do a re-render here instead or is it too costy 
     this.ui.quantity.val(this.model.get("quantity")); 
    } 
}); 

var ItemCollection = Backbone.Collection.extend({ 
    model: ItemModel 
}); 



var CategoryModel = Backbone.Model.extend({ 
    defaults: { 
     name: '' 
    } 
}); 

var CategoryView = Backbone.Marionette.CompositeView.extend({ 

    template: '#template-category', 

    itemViewContainer: ".menu-items", 
    itemView: ItemView, 

    className: "tab-pane", 
    id: function(){ 
     return "category-" + this.model.get("id"); 
    }, 

    initialize: function() { 

     this.collection = new ItemCollection(); 
     var that = this; 
     _(this.model.get("menu_items")).each(function (menu_item) { 
      that.collection.add(new ItemModel({ 
       id: menu_item.id, 
       name: menu_item.name, 
       price: menu_item.price, 
       desc: menu_item.desc 
      })); 
     }); 


    } 
}); 


var CategoryCollection = Backbone.Collection.extend({ 
    url: '/api/categories', 
    model: CategoryModel 
}); 

var CategoryCollectionView = Backbone.Marionette.CompositeView.extend({ 

    el_tabs: '#categories-tabs', 

    template: '#template-menu-core', 
    itemViewContainer: ".tab-content", // This is where I'm getting the error 
    itemView: CategoryView, 

    onItemAdded: function (itemView) { 
     alert("halalouya"); 
     //this.$el.append("<li><a href=\"#cateogry-" + tab.get("id") + "\">" + tab.get("name") + "</a></li>"); 

     //$(this.el_tabs).append("<li><a href='#category-" + itemView.model.get("id") + "'>" 
      //+ itemView.model.get("name") + "</a></li>") 
    } 
}); 

Tôi biết Đó là một chút khó khăn để làm theo nhưng các bạn là phương sách cuối cùng của tôi. Không có vấn đề với các mẫu và quyến rũ cateogry và những thứ khác (nó đã làm việc trước khi chuyển đổi các CategoryCollectionView từ một bộ sưu tập rối đến một cái nhìn composite.)

Sửa 1

Added App initalizer trên yêu cầu:

  AllegroWidget = new Backbone.Marionette.Application(); 

      AllegroWidget.addInitializer(function (options) { 

       // load templates and append them as scripts 
       inject_template([ 
         { id: "template-menuitem", path: "/js/templates/ordering-widget-menuitem.html" }, 
         { id: "template-category", path: "/js/templates/ordering-widget-category.html" }, 
         { id: "template-menu-core", path: "/js/templates/ordering-widget-menu-core.html" }, 
         { id: "template-skeleton", path: "/js/templates/ordering-widget-skeleton.html" } 
        ]); 

       // create app layout using the skeleton 
       var AppLayout = Backbone.Marionette.Layout.extend({ 
        template: "#template-skeleton", 

        regions: { 
         order_summary: "#order-summary", 
         categories: "#categories-content" 
        } 
       }); 

       AllegroWidget.layout = new AppLayout(); 
       var layoutRender = AllegroWidget.layout.render(); 
       jQuery("#allegro-ordering-widget").html(AllegroWidget.layout.el); 

       // Initialize the collection and views 
       var _category_collection = new CategoryCollection(); 

       var _cateogories_view = new CategoryCollectionView({ api_key: window.XApiKey, collection: _category_collection }); 


       _category_collection.fetch({ 
        beforeSend: function (xhr) { 
         xhr.setRequestHeader("X-ApiKey", window.XApiKey); 
        }, 
        async: false 
       }); 


       //AllegroWidget.addRegions({ 
       /// mainRegion: "#allegro-ordering-widget" 
       //}); 
       AllegroWidget.layout.categories.show(_cateogories_view); 

      }); 



      AllegroWidget.start({api_key: window.XApiKey}); 
+0

lưu ý không liên quan. Tôi nhận thấy bạn đang sử dụng onItemAdded trong mã của bạn. Nó đã được thay đổi gần đây, bạn sẽ muốn sử dụng onBeforeItemAdded. Xem câu trả lời của tôi trong bài đăng này http://stackoverflow.com/questions/16180159/adding-a-model-to-a-marionette-collectionviews-collection-doesnt-trigger-onite/16195832#16195832 –

+0

Bạn có thể chia sẻ mã không tạo một thể hiện của CategoryCollectionView và gọi region.show()? –

+0

@ScottPuleo cảm ơn mẹo, chỉ đang đấu tranh với điều đó, tôi đã gắn trình khởi tạo ứng dụng vào câu hỏi –

Trả lời

6

Bạn đang thêm vào bộ sưu tập thông qua tìm nạp trước khi bạn gọi hiển thị trên khu vực.

Marionette.CompositeView được gắn theo mặc định để nối thêm ItemViews khi các mô hình được thêm vào bộ sưu tập của nó. Đây là một vấn đề như itemViewContainer .tab-content chưa được thêm vào dom vì show chưa được gọi trên vùng.

Dễ sửa, làm lại bạn mã như dưới đây và nó sẽ hoạt động mà không bị quá tải appendHtml.

// Initialize the collection and views 
var _category_collection = new CategoryCollection(); 

// grab a promise from fetch, async is okay 
var p = _category_collection.fetch({headers: {'X-ApiKey': window.XApiKey}); 

// setup a callback when fetch is done 
p.done(function(data) { 
    var _cateogories_view = new CategoryCollectionView({ api_key: window.XApiKey, collection: _category_collection }); 
    AllegroWidget.layout.categories.show(_cateogories_view); 
}); 
+0

@ScottPuelo công cụ tuyệt vời người đàn ông –

+0

Điều này đã giúp tôi rõ ràng lên kiến ​​trúc marionette của tôi rất nhiều .. bất cứ điều gì thực sự làm việc bây giờ. CẢM ƠN. – MBHNYC

0

ổn này là khá lạ nhưng thêm này trong lớp CategoryCollectionView:

appendHtml: function (collectionView, itemView, index) { 
    //@todo very weird stuff, assigning '.tab-content' to itemViewContainer should have been enough 
    collectionView.$(".tab-content").append(itemView.el); 
} 

giải quyết vấn đề, tuy nhiên tôi không có ý tưởng tại sao nó hoạt động, asssigning '.tab-nội dung' để itemViewContainer nên đã được đủ, bất kỳ ý tưởng?

+0

Điều này hoạt động vì 'tab-nội dung' ở đây được mã hóa cứng trong phương thức xem. –

+0

Sự cố có vẻ như trong phương thức getItemViewContainer dường như được gọi trước khi mẫu được hiển thị. Tôi đã ghi đè phương thức đó và xóa lỗi, sau đó nó hoạt động. –