Skip to content
This repository was archived by the owner on Mar 7, 2024. It is now read-only.

Commit c21e0e9

Browse files
committed
네스팅된 리스트 제대로 지원.
1 parent 250cde0 commit c21e0e9

File tree

5 files changed

+66
-26
lines changed

5 files changed

+66
-26
lines changed

Compiler/Program.cs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,10 @@ static Template ParseTemplate(HtmlNode templateNode, string namePrefix)
7272
template.ClassName = namePrefix + template.TemplateId;
7373
template.ModelName = templateNode.Attributes["j8-model"]?.Value;
7474

75-
var childNodes = templateNode.SelectNodes(".//*");
76-
if (childNodes != null)
77-
{
78-
var listItemNodes = childNodes.Where(x => x.GetAttributeValue("j8-listItem", null) != null);
79-
foreach (var node in listItemNodes)
80-
{
81-
node.Remove(); // 지금 떼어놔야 바로 다음에 컨트롤 검색에서 빠진다.
82-
template.ListItems.Add(ParseTemplate(node, template.ClassName + "_"));
83-
}
84-
}
75+
ScanListItems(template, templateNode);
8576

8677
// j8-listItem 붙은 것들을 뗀 상태에서 다시 검색한다
87-
childNodes = templateNode.SelectNodes(".//*");
78+
var childNodes = templateNode.SelectNodes(".//*");
8879
if (childNodes != null)
8980
{
9081
var controlNodes = childNodes.Where(x => x.GetAttributeValue("j8-control", null) != null);
@@ -105,6 +96,25 @@ static Template ParseTemplate(HtmlNode templateNode, string namePrefix)
10596
return template;
10697
}
10798

99+
static void ScanListItems(Template template, HtmlNode baseNode)
100+
{
101+
if (!baseNode.HasChildNodes) { return; }
102+
103+
// 순회 중 컨테이너 변경이 일어나기 때문에 ToArray로 한번 복사해서 순회
104+
foreach (var node in baseNode.ChildNodes.ToArray())
105+
{
106+
if (node.Attributes.Contains("j8-listItem"))
107+
{
108+
node.Remove(); // 지금 떼어놔야 바로 다음에 컨트롤 검색에서 빠진다.
109+
template.ListItems.Add(ParseTemplate(node, template.ClassName + "_"));
110+
}
111+
else
112+
{
113+
ScanListItems(template, node);
114+
}
115+
}
116+
}
117+
108118
static void CheckNode(Template template, HtmlNode node)
109119
{
110120
var textMatched = pattern.Matches(node.InnerText);

Library/jul8.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,21 +101,9 @@
101101
fields: Fields;
102102

103103
constructor(root: JQuery, scanFields: boolean) {
104-
// 리스트 항목은 부모로부터 뗀다.
105-
// 그래야 처음에는 없고, 추가하는 만큼 붙일 수 있으니까.
106-
root.find('[j8-listItem]').each(
107-
(i, v) => {
108-
let itemId = v.getAttribute('j8-listItem');
109-
110-
if (this.lists[itemId]) {
111-
console.error('(Jul8) duplicate listItem id: [' + itemId + ']')
112-
}
113-
114-
let j = $(v);
115-
let p = j.parent();
116-
j.detach();
117-
this.lists[itemId] = { list: p, itemTemplate: j };
118-
});
104+
// 먼저 리스트 항목을 찾아서 부모로부터 뗀다.
105+
// 그래야 처음에는 없고, 추가하는 만큼 클론해서 붙일 수 있으니까.
106+
this.scanListItem(root.get(0));
119107

120108
// 템플릿과 다르게 컨트롤들은 부모로부터 떼지 않는다.
121109
// 이미 템플릿 단위로 복제 생성된 상태이기 때문.
@@ -135,6 +123,27 @@
135123
}
136124
}
137125

126+
private scanListItem(baseElem: Element) {
127+
for (let i = 0; i < baseElem.children.length; ++i) {
128+
let elem = baseElem.children[i];
129+
130+
if (elem.hasAttribute('j8-listItem')) {
131+
let itemId = elem.getAttribute('j8-listItem');
132+
if (this.lists[itemId]) {
133+
console.error('(Jul8) duplicate listItem id: [' + itemId + ']')
134+
}
135+
136+
let j = $(elem);
137+
let p = j.parent();
138+
j.detach();
139+
this.lists[itemId] = { list: p, itemTemplate: j };
140+
}
141+
else {
142+
this.scanListItem(elem);
143+
}
144+
}
145+
}
146+
138147
private visitElem(elem: Element) {
139148
let childNodes = elem.children;
140149
if (childNodes.length > 0) {

Sample/html/sample_templates.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
<th>번호</th>
3939
<th>내용</th>
4040
<th>INPUT</th>
41+
<th>네스팅된 리스트</th>
4142
<th>동작</th>
4243
</tr>
4344
</thead>
@@ -52,6 +53,9 @@
5253
<td>
5354
<input j8-control="inNum" type="text" value="{{ inNum }}" />
5455
</td>
56+
<td>
57+
<span j8-listItem="Tag" class="label label-default" style="margin-right:2pt"></span>
58+
</td>
5559
<td>
5660
<button j8-control="btnReflect" class="btn btn-default btn-xs">입력 반영</button>
5761
<button j8-control="btnRemove" class="btn btn-default btn-xs">지우기</button>

Sample/main.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class MyTable extends MyTable_d {
3838
let v = tr.inNum.val();
3939
tr.set({ num: v, inNum: v });
4040
});
41+
42+
tr.listOf_Tag.add(MyTable_TR_Tag_d).$.text('Tag1');
43+
tr.listOf_Tag.add(MyTable_TR_Tag_d).$.text('Tag2');
44+
tr.listOf_Tag.add(MyTable_TR_Tag_d).$.text('Tag3');
4145
}
4246

4347
summarize(): string {

Sample/sample_templates.g.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class MyTable_TR_d implements Jul8.View
4444
inNum: JQuery;
4545
btnReflect: JQuery;
4646
btnRemove: JQuery;
47+
listOf_Tag: Jul8.ViewList<MyTable_TR_Tag_d>;
4748

4849
constructor($: JQuery)
4950
{
@@ -54,6 +55,7 @@ class MyTable_TR_d implements Jul8.View
5455
this.inNum = s.C('inNum');
5556
this.btnReflect = s.C('btnReflect');
5657
this.btnRemove = s.C('btnRemove');
58+
this.listOf_Tag = s.L<MyTable_TR_Tag_d>('Tag');
5759
}
5860

5961
private j8fields: Jul8.Fields;
@@ -64,3 +66,14 @@ class MyTable_TR_d implements Jul8.View
6466
this.j8fields.set(data);
6567
}
6668
}
69+
70+
class MyTable_TR_Tag_d implements Jul8.View
71+
{
72+
$: JQuery;
73+
74+
constructor($: JQuery)
75+
{
76+
this.$ = $;
77+
let s = new Jul8.Scanner(this.$, false);
78+
}
79+
}

0 commit comments

Comments
 (0)