Marionette应用程序的ChildView错误

时间:2014-07-05 05:31:07

标签: backbone.js marionette

我是骨干和木偶的新手,并从Packpub出版的书Getting Started with Backbone Marionette中学习。
我收到的错误为Uncaught NoChildViewError: A "childView" must be specified 我的代码是

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Marionette test app</title>
  <link  rel="stylesheet" media="screen" href="{{ url_for('static', filename='bootstrap.css') }}">
   <style type="text/css">
        .container {
            margin-top: 10px;
        }
         body {
            padding-top: 60px;
            padding-bottom: 40px;
         }

   </style>
</head>
<body>

<div id="container" class="well">
    <h2>Marionette Views- CollectionView</h2>
</div>

 <script id="categoryTemplate" type="text/template">
    <a href="#<%= name%>" ><%= name%> (<%= booksOnCategory %>)</a>
        <button class="info">Details</button>
</script>


<script src="{{ url_for('static', filename='jquery.js') }}"></script>
<script src="{{ url_for('static', filename='bootstrap.js') }}"></script>
<script src="{{ url_for('static', filename='underscore.js') }}"></script>
<script src="{{ url_for('static', filename='backbone.js') }}"></script>
<script src="{{ url_for('static', filename='backbone.marionette.js') }}"></script>


<script type="application/javascript">
    // lets create new application as below;
    var BookStoreApp = new Backbone.Marionette.Application();


    var BookStoreController = Backbone.Marionette.Controller.extend({
        displayBooks : function(){
            console.log("I will display books");
        }
    });

    var BookStoreRouter = Backbone.Marionette.AppRouter.extend({
        controller : BookStoreController,
        appRoutes : {
            "":"displayBooks"
        }
    });

    BookStoreApp.addInitializer(function(){
        var controller = new BookStoreController();
        var router = new BookStoreRouter({controller: controller});
        console.log("Hello from addInit");
    });

    BookStoreApp.on("initialize:after", function(){
        if (Backbone.history){
            Backbone.history.start();
            console.log("hello from initialize:after.. .");
        }

    });


    BookModel = Backbone.Model.extend({
        defaults : {
            name : "",
            booksOnCategory:0
        }
    });

    BookCollection = Backbone.Collection.extend({
        model : BookModel
    });

    var bookModel = new BookModel({name:"Math", booksOnCategory:3});
    var bookModel2 = new BookModel({name:"Art", booksOnCategory:5});
    var bookModel3 = new BookModel({name:"Science", booksOnCategory:6});
    var bookModel4 = new BookModel({name:"Biology", booksOnCategory:1});
    var bookCollection = new BookCollection([bookModel, bookModel2, bookModel3, bookModel4]);

    var BookView = Backbone.Marionette.ItemView.extend({
        template : '#book-template',
        tagName: 'li',
        events:{
            "mouseenter .info": "showDetails",
            "mouseleave .info": "hideDetails"
        },
        showDetails: function(){
            this.$(".info").popover({
                title: this.model.get('name'),
                content: "we have "+ this.model.get("booksOnCategory") + " left"
            });
            this.$(".info").popover("show");
        },
        hideDetails: function(){
            this.$(".info").popover("hide");
        }
    });

    CategoriesVieww = Backbone.Marionette.CollectionView.extend({
        tagName: 'ul',
        className: "unstyled",
        itemView: BookView
    });

    var CategoriesView = new CategoriesVieww({
        collection: bookCollection,
        el: "#container" });

    CategoriesView.render();

    BookStoreApp.start();

</script>

</body>
</html>

注意:我正在flask-jinja2 app上测试这个应用程序;所以忽略脚本标记中的url_for;因为他们是jinja2的要求

2 个答案:

答案 0 :(得分:11)

看起来问题正是错误消息所说的;)CollectionView是作为一系列子视图生成的,而need to tell the collection view是您想要为这些子视图使用的视图类型。

但你还没有。也许只是一个错字?尝试将CategoriesVieww更改为

CategoriesVieww = Backbone.Marionette.CollectionView.extend({
    tagName: 'ul',
    className: "unstyled",
    childView: BookView    // <-- here
});

答案 1 :(得分:6)

如果您使用的是collectionView或Marionette 2.2.0或更高版本的compositeView,请注意API关键字已更改如下:

  

itemView现在称为childView   itemViewContainer现在称为childViewContainer

2.2.0之前

CategoriesView = Backbone.Marionette.CompositeView.extend({
    template: '#template',
    className: "unstyled",
    itemView: BookView    // <-- here
    itemViewContainer: "#books-list"
});

我花了一段时间才通过Firebug调试器搞清楚。您可以参考https://docs.google.com/document/d/1fuXb9N5LwmdPn-teMwAo3c8JTx6ifUowbqFY1NNSdp8/edit#了解API更改。并非所有变化都记录在我能找到的任何地方。

2.2.0之后:

CategoriesView = Backbone.Marionette.CompositeView.extend({
    template: '#template',
    className: "unstyled",
    childView: BookView    // <-- here
    childViewContainer: "#books-list"
});