私はこのJavascript/JSON/Handlebarsに関してまったく新しいのですが、2つのネストされたレベルを持つJSONオブジェクトをHandlebarsテンプレートで動作させるのに問題があります。
JSONLintでJSONオブジェクトを検証したので、それは有効なJSONコードですが、テンプレートを正しく動作させるための正しいJSON形式があるかどうかはわかりません。 :)(別のシステムで手動でJSONを構築しています。)または、テンプレートの構文が間違っている可能性があります。それが私が知りたいことです...
簡単な説明:このオブジェクトは目次です。チャプターがあり、各チャプター内に映画があります。したがって、映画は各チャプター要素のネストされた要素です。
次のようなHTML出力が必要です。
Chapter1: ChapterName
Movie1: MovieName
Movie2: MovieName
Chapter2: Chaptername
Movie1: MovieName
Movie2: MovieName
Movie3: MovieName
データのインスタンスが1つだけ(JSONオブジェクトの最後の要素)になるか、まったく何も得られないようです。 (どのTweakまたはバージョンを試すかによって異なります。)ブラウザコンソールにエラーが表示されません。
これまでに使用しようとしてきたすべてのコード(スクリプト、HTML、テンプレートなど)は次のとおりです。
<!DOCTYPE html>
<html>
<head> <meta charset="UTF-8">
<title>Handlebars Demo</title>
<!-- dependant files -->
<script src="Handlebars.js"></script>
</head>
<!-- template -->
<script id="template2" type="text/x-handlebars-template">
<div>Chapter stuff:</div>
<ul>{{#each Chapter}}
<ol>{{@index}} {{ChapterName}}
{{#each movies}}
<li>Movie ID:{{movieIDnum}}</li>
{{/each}}
</ol>
{{/each}}
</ul>
</script>
<body><div id="main"></div></body>
<script>
var source = document.getElementById('template2').innerHTML;
var template = Handlebars.compile(source);
var data = {
"Chapter" : {
"ChapterName" : "Introduction",
"chapterNum" : "1",
"movies" : [
{
"movieIDnum" : "16244028",
"movieName" : "Update Test Movie 0",
"movieFileName" : "Test0.mov",
"moviePositionInChapter" : "1"
}
]
},
"Chapter" : {
"ChapterName" : "Welcome",
"chapterNum" : "2",
"movies" : [
{
"movieIDnum" : " 17322365",
"movieName" : "Update Test movie 1",
"movieFileName" : "Test1.mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 17326267",
"movieName" : "Update Test movie 3",
"movieFileName" : "Test3.mov",
"moviePositionInChapter" : "2"
}
]
},
"Chapter" : {
"ChapterName" : "The new Interface",
"chapterNum" : "2",
"movies" : [
{
"movieIDnum" : " 1732123476",
"movieName" : "Update Test movie 12",
"movieFileName" : "Test12.mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 173262373",
"movieName" : "Update Test movie 9",
"movieFileName" : "Test9.mov",
"moviePositionInChapter" : "2"
},
{
"movieIDnum" : " 173273474",
"movieName" : "Update Test movie 10",
"movieFileName" : "Test10.mov",
"moviePositionInChapter" : "3"
}
]
},
"Chapter" : {
"ChapterName" : "What is an Update?",
"chapterNum" : "4",
"movies" : [
{
"movieIDnum" : " 177342131",
"chapterNum" : "4",
"chapterName" : "What is an Update?",
"movieName" : "Test movie again",
"movieFileName" : "Test13.mov",
"moviePositionInChapter" : "1"
}
]
},
"Chapter" : {
"ChapterName" : "Editing",
"chapterNum" : "5",
"movies" : [
{
"movieIDnum" : " 173290878",
"movieName" : "Update Test movie 14",
"movieFileName" : "Test14mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 177344914",
"movieName" : " Movie 15 Test",
"movieFileName" : "Test233.mov",
"moviePositionInChapter" : "2"
}
]
}
}
var result = template(data);
document.write(result);
</script>
</html>
これが機能しない理由を知りたいのですが、「まったく別の形式で他の4つのことを使って問題を解決する方法」だけではありません。これは、私が使用しようとしているツールで動作可能であるべきだと私は理解しています。これらのツールをよりよく理解し、解決策を得るだけでなく、プロセスから学びたいと思います。 (あなたが知っている、釣りをする人を教える... :))
ありがとう、J
提案する変更点がいくつかあります。最初に、いくつかのキーを持つオブジェクトを記述しないでください{ Chapter:, Chapter:, etc...}
もう1つの提案は、ハンドルバーの動作を確認することです。すべての場合にそれぞれが必要なわけではありません。それが明確になることを願っています。
これらの変更を試してください:
<!DOCTYPE html>
<html>
<head> <meta charset="UTF-8">
<title>Handlebars Demo</title>
<!-- dependant files -->
<script src="handlebars.js"></script>
</head>
<!-- template -->
<script id="template2" type="text/x-handlebars-template">
<div>Chapter stuff:</div>
<ul>{{#Chapters}}
<ol>{{@index}} {{ChapterName}}
{{#movies}}
<li>Movie ID:{{movieIDnum}}</li>
{{/movies}}
</ol>
{{/Chapters}}
</ul>
</script>
<body><div id="main"></div></body>
<script>
var source = document.getElementById('template2').innerHTML;
var template = Handlebars.compile(source);
var data = [
{
"ChapterName" : "Introduction",
"chapterNum" : "1",
"movies" : [
{
"movieIDnum" : "16244028",
"movieName" : "Update Test Movie 0",
"movieFileName" : "Test0.mov",
"moviePositionInChapter" : "1"
}
]
},
{
"ChapterName" : "Welcome",
"chapterNum" : "2",
"movies" : [
{
"movieIDnum" : " 17322365",
"movieName" : "Update Test movie 1",
"movieFileName" : "Test1.mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 17326267",
"movieName" : "Update Test movie 3",
"movieFileName" : "Test3.mov",
"moviePositionInChapter" : "2"
}
]
},
{
"ChapterName" : "The new Interface",
"chapterNum" : "2",
"movies" : [
{
"movieIDnum" : " 1732123476",
"movieName" : "Update Test movie 12",
"movieFileName" : "Test12.mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 173262373",
"movieName" : "Update Test movie 9",
"movieFileName" : "Test9.mov",
"moviePositionInChapter" : "2"
},
{
"movieIDnum" : " 173273474",
"movieName" : "Update Test movie 10",
"movieFileName" : "Test10.mov",
"moviePositionInChapter" : "3"
}
]
},
{
"ChapterName" : "What is an Update?",
"chapterNum" : "4",
"movies" : [
{
"movieIDnum" : " 177342131",
"chapterNum" : "4",
"chapterName" : "What is an Update?",
"movieName" : "Test movie again",
"movieFileName" : "Test13.mov",
"moviePositionInChapter" : "1"
}
]
},
{
"ChapterName" : "Editing",
"chapterNum" : "5",
"movies" : [
{
"movieIDnum" : " 173290878",
"movieName" : "Update Test movie 14",
"movieFileName" : "Test14mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 177344914",
"movieName" : " Movie 15 Test",
"movieFileName" : "Test233.mov",
"moviePositionInChapter" : "2"
}
]
}
];
var result = template({Chapters: data});
document.write(result);
</script>
</html>
pdjotaは正解です。この回答は、必要に応じて、各ブロックヘルパーの使用方法を示すためのものです。
Pdjotaが賢明に指摘したように、オブジェクトの要素はすべて同じキー、つまり「Chapter」を持つため、オブジェクトの要素を上書きしています。したがって、data
を、同じキーを持つオブジェクトのオブジェクトではなく、オブジェクトの配列に変換します。
その場合でも、data
をtemplate()
に渡すことができます。欠けていたのは、各ブロックで使用されているオブジェクトのプロパティを参照する方法でした。それはthis
で行われます。たとえば、moviesイテレータを使用している場合、moviesオブジェクトのプロパティはthis.movieIDnum
、this.movieName
などのように参照されます。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Handlebars Demo</title>
<!-- dependant files -->
<script src="Handlebars.js"></script>
</head>
<!-- template -->
<script id="template2" type="text/x-handlebars-template">
<div>Chapter stuff:</div>
<ul>
{{#each this}}
<ol>Chapter{{this.chapterNum}}: {{this.ChapterName}}
{{#each movies}}
<li>Movie{{this.moviePositionInChapter}}: {{this.movieName}}</li>
{{/each}}
</ol>
{{/each}}
</ul>
</script>
<body><div id="main"></div></body>
<script>
var source = document.getElementById('template2').innerHTML;
var template = Handlebars.compile(source);
var data = [
{
"ChapterName" : "Introduction",
"chapterNum" : "1",
"movies" : [
{
"movieIDnum" : "16244028",
"movieName" : "Update Test Movie 0",
"movieFileName" : "Test0.mov",
"moviePositionInChapter" : "1"
}
]
},
{
"ChapterName" : "Welcome",
"chapterNum" : "2",
"movies" : [
{
"movieIDnum" : " 17322365",
"movieName" : "Update Test movie 1",
"movieFileName" : "Test1.mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 17326267",
"movieName" : "Update Test movie 3",
"movieFileName" : "Test3.mov",
"moviePositionInChapter" : "2"
}
]
},
{
"ChapterName" : "The new Interface",
"chapterNum" : "2",
"movies" : [
{
"movieIDnum" : " 1732123476",
"movieName" : "Update Test movie 12",
"movieFileName" : "Test12.mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 173262373",
"movieName" : "Update Test movie 9",
"movieFileName" : "Test9.mov",
"moviePositionInChapter" : "2"
},
{
"movieIDnum" : " 173273474",
"movieName" : "Update Test movie 10",
"movieFileName" : "Test10.mov",
"moviePositionInChapter" : "3"
}
]
},
{
"ChapterName" : "What is an Update?",
"chapterNum" : "4",
"movies" : [
{
"movieIDnum" : " 177342131",
"chapterNum" : "4",
"chapterName" : "What is an Update?",
"movieName" : "Test movie again",
"movieFileName" : "Test13.mov",
"moviePositionInChapter" : "1"
}
]
},
{
"ChapterName" : "Editing",
"chapterNum" : "5",
"movies" : [
{
"movieIDnum" : " 173290878",
"movieName" : "Update Test movie 14",
"movieFileName" : "Test14mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 177344914",
"movieName" : " Movie 15 Test",
"movieFileName" : "Test233.mov",
"moviePositionInChapter" : "2"
}
]
}
];
var result = template(data);
document.write(result);
</script>
</html>