Looping over a JSON object in order to render it as HTML in my Component Template. Re-using a inline ng-template for outputting the HTML.
From the first iteration I am not able to access the Ojbect properties on level
since it is undefined
, however, the output HTML-like tree structure is build up exactly as the JSON is. Seems like i'm not passing the oject variable in the correct order.
JSON
{ "content": [
{
"tag": "paragraph",
"html": "\r\n",
"children": [
{
"tag": "header",
"level": "1",
"html": "\r\n91\/439\/EC Driving Licences"
},
{
"tag": "header",
"level": "2",
"html": "\r\nANNEX II - chapter II"
}
]
},
{
"tag": "br"
},
{
"tag": "paragraph",
"children": [
{
"tag": "table",
"html": "\r\n",
"children": [
{
"tag": "tr",
"children": [
{
"tag": "td",
"html": "II ."
},
{
"tag": "td",
"html": "\r\nMember States may implement the appropriate measures to ensure that drivers who have lost the knowledge, skills and behaviour as described under points 1 to 9 can recover this knowledge and these skills and will continue to exhibit such behaviour required for driving a motor vehicle.",
"children": [
{
"tag": "br"
},
{
"tag": "br"
},
{
"tag": "list",
"type": "disc",
"html": "\r\n",
"children": [
{
"tag": "li",
"html": "Recognise traffic dangers and assess their seriousness;"
},
{
"tag": "li",
"html": "Have sufficient command of their vehicle not to create dangerous situations and to react appropriately should such situations occur;"
},
{
"tag": "li",
"html": "Comply with road traffic regulations, and in particular those intended to prevent road accidents and to maintain the flow of traffic;"
},
{
"tag": "li",
"html": "Detect any major technical faults in their vehicles, in particular those posing a safety hazard, and have them remedied in an appropriate fashion;"
},
{
"tag": "li",
"html": "Take account of all the factors affecting driving behaviour (e.g. alcohol, fatigue, poor eyesight, etc.) so as to retain full use of the faculties needed to drive safely;"
},
{
"tag": "li",
"html": "Help ensure the safety of all road users, and in particular of the weakest and most exposed by showing due respect for others."
}
]
}
]
}
]
}
]
}
]
}
]
}
Template
<div *ngFor="let rootLevel of jsonHTML; let i = index;">
<span *ngIf="rootLevel.tag">{{i}} [{{rootLevel.tag}}]</span {{rootLevel.html}}
<ng-container *ngTemplateOutlet="nextLevelTemplate; context: { level: rootLevel.children, index: i }">
</ng-container>
</div>
<ng-template #nextLevelTemplate let-level="level" let-i="index">
<span *ngIf="level && level.tag">[{{level.tag}}]</span><span *ngIf="level && level.html">[{{level.html}}]</span>
[tag]{{level?.tag}}[/tag]
[html]{{level?.html}}[/html]
-{{level | json}}-
<div *ngFor="let nextLevel of level; let i = index;">
<ng-container *ngTemplateOutlet="nextLevelTemplate; context: { level: nextLevel.children, index: i }">
</ng-container>
</div>
</ng-template>
Output
0 [paragraph]
0 -[object Object],[object Object]-
0 [tag][/tag] [html][/html] --
1 [tag][/tag] [html][/html] --
1 [br] 1 [tag][/tag] [html][/html] --
2 [paragraph] 2 [tag][/tag] [html][/html] -[object Object]-
0 [tag][/tag] [html][/html] -[object Object]-
0 [tag][/tag] [html][/html] -[object Object],[object Object]-
0 [tag][/tag] [html][/html] --
1 [tag][/tag] [html][/html] -[object Object],[object Object],[object Object]-
0 [tag][/tag] [html][/html] --
1 [tag][/tag] [html][/html] --
2 [tag][/tag] [html][/html] -[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]-
0 [tag][/tag] [html][/html] --
1 [tag][/tag] [html][/html] --
2 [tag][/tag] [html][/html] --
3 [tag][/tag] [html][/html] --
4 [tag][/tag] [html][/html] --
5 [tag][/tag] [html][/html] --
Output and screenshot of the following JSON node
"children": [
{
"tag": "header",
"level": "1",
"html": "\r\n91\/439\/EC Driving Licences"
},
{
"tag": "header",
"level": "2",
"html": "\r\nANNEX II - chapter II"
}
]
As you can see there are 2 items in the Array, template loops over it twice, but tag
and html
properties cant be accessed.
Is this is scoping issue, that ng-template cant be re-used in this way?
答案 0 :(得分:0)
我的问题的答案是:Recursive ng-template references
确实是一个范围问题。显然,这一切都是关于以正确的方式绕过范围。
<!-- Define the recursive template. -->
<ng-template #nodeTemplateRef let-node>
<div class="node" [class.node--selected]="( node === selectedTreeNode )">
<a (click)="selectNode( node )" class="node__label">
{{ node.label }}
</a>
<div *ngIf="node.children.length" class="node__children">
<!-- Invoke the recursive template. -->
<ng-template
ngFor
[ngForOf]="node.children"
[ngForTemplate]="nodeTemplateRef">
<!--
NOTE: The "$implicit" property of the ngFor context is what will
be made available to the template ref's implicit let-node binding.
-->
</ng-template>
</div>
</div>
</ng-template>
<ng-template
[ngTemplateOutlet]="nodeTemplateRef"
[ngTemplateOutletContext]="{ $implicit: data.root }">
</ng-template>
<p class="note">
<em>Ng-For Template Rendering</em>
</p>
... ngFor指令成功地以递归方式呈现了定义它的ngTemplate。
使用ngFor指令时,无法显式传入“上下文”对象-ngFor指令隐式传入ngForContext对象作为模板上下文。这意味着我的ng-template指令必须使用ngFor上下文的“隐式”导出作为“ let-node”模板绑定。
在这种情况下,这不是问题,因为我只想传递一个值。但是,为了获得更大的灵活性,我们可以放弃ngFor指令,而仅使用另一个ng-template递归呈现模板(与使用ng-template实例启动递归的方式几乎相同)...