#backbone.js #marionette
#backbone.js #марионетка
Вопрос:
Я новичок в backbone и marionette и узнал об этом из книги Getting Started with Backbone Marionette
издательства Packpub.
Я получаю ошибку как 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; поэтому игнорируйте url_for
тег in script; поскольку они требуются для jinja2
Ответ №1:
Похоже, проблема именно в том, о чем говорится в сообщении об ошибке 😉 CollectionView создается как последовательность дочерних представлений, и вам нужно указать представлению коллекции, какой тип представления вы хотите использовать для этих дочерних представлений.
Но это не так. Возможно, просто опечатка? Попробуйте изменить свой CategoriesVieww
на
CategoriesVieww = Backbone.Marionette.CollectionView.extend({
tagName: 'ul',
className: "unstyled",
childView: BookView // <-- here
});
Комментарии:
1. @namit marionette не так давно обновился до версии 2.0, я помню, как читал, что одной из вещей, которые они изменили, было переименование ItemView в childView. Это произошло совсем недавно, многие справочники, вероятно, еще не успели обновиться. полный журнал изменений можно найти здесь, поскольку было несколько изменений имени, которые могли бы вас зацепить при использовании ресурса для предыдущей версии docs.google.com/document/d /…
2. Однако был бы осторожен. Я попробовал следующий учебник с новой версией библиотеки: davidsulc.com/blog/2013/02/03/… Это отлично работало с предыдущей версией, но теперь поведение, похоже, изменилось, и оно работает не так, как ожидалось.
Ответ №2:
Если вы используете CollectionView ИЛИ CompositeView из Marionette 2.2.0 или выше, имейте в виду, что ключевые слова API изменились следующим образом:
ItemView теперь называется childView itemViewContainer теперь называется childViewContainer
ДО версии 2.2.0
CategoriesView = Backbone.Marionette.CompositeView.extend({
template: '#template',
className: "unstyled",
itemView: BookView // <-- here
itemViewContainer: "#books-list"
});
Мне потребовалось некоторое время, чтобы разобраться с этим с помощью Firebug debugger. Вы можете обратиться к 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"
});