Это моя версия Angular CLI:
Angular CLI: 7.3.9
Node: 12.2.0
OS: win32 x64
Angular: 8.0.2
При создании приложения Angular 8 я пытаюсь использовать вложенные группы форм, которые соответствуют следующему объекту:
const Boilerplate: any = {
1: {
desc: "section1",
content: {
1: "question 1.a:",
2: "question 1.b:",
3: "question 1.c"
}
},
2: {
desc: "section2",
content: {
4: "question 2.a:",
5: "question 2.b:",
6: "question 2.c",
7: "question 2.d"
}
}
}
Существует внутренняя группа форм FormControls для раздела 1 и раздела 2, а также внешняя группа форм, содержащая две внутренние группы форм. Это определено в файле component.ts.
В component.html я пытаюсь выполнить итерацию через внутреннюю группу форм внешней группы форм и распечатать внутренние элементы управления формами. Это код, который у меня есть до сих пор:
<form [formGroup] = "sectionGroup">
<div *ngIf = "boilerplate">
<div *ngFor = "let section of boilerplate | keyvalue">
{{ boilerplate[section.key].desc }}
<div formGroupName = "{{section.key}}">
<div *ngFor = "let question of boilerplate[{{section.key}}]">
<-- things -->
</div>
</div>
</div>
</div>
Строка <div *ngFor = "let question of boilerplate[{{section.key}}]"> завершается с ошибкой:
Unexpected token {, expected identifier, keyword, or string
Я пробовал следующие решения, ни одно из которых не помогло мне:
<div *ngFor = "let question of {{boilerplate}}.{{section.key}}">
<div *ngFor = "let question of {{boilerplate[section.key]}}">
<div *ngFor = "let question of {{boilerplate[{{section.key}}]}}">
<td *ngFor = "let question of Section">{{boilerplate[[section.key]]}}</td>
Я пробовал множество других комбинаций и порядков {} и [] и теперь понимаю, что вложенная интерполяция не поддается разбору.
Есть ли у кого-нибудь предложение о том, как я могу этого добиться? Я использую вложенные группы форм, потому что в будущем у меня могут появиться дополнительные слои секций. Формат объекта Boilerplate можно изменить, если это сделает проблему решаемой (потому что я определил его сам).
РЕДАКТИРОВАТЬ
Следующее было решением, которое решило эту проблему:
<div *ngFor = "let question of boilerplate[section.key].content | keyvalue">
{{question.value}}
</div>






Я пытаюсь, как показано ниже,
<div [formGroup] = "formGroup">
<div *ngIf = "boilerplate">
<div *ngFor = "let section of boilerplate | keyvalue">
{{ boilerplate[section.key].desc }}
<div>
<div *ngFor = "let question of boilerplate[section.key].content | keyvalue">
{{ question | json }}
</div>
</div>
</div>
Вывод, как показано ниже,
section1
{ "key": "1", "value": "question 1.a:" }
{ "key": "2", "value": "question 1.b:" }
{ "key": "3", "value": "question 1.c" }
section2
{ "key": "4", "value": "question 2.a:" }
{ "key": "5", "value": "question 2.b:" }
{ "key": "6", "value": "question 2.c" }
{ "key": "7", "value": "question 2.d" }
Вам нужно использовать канал фильтра ключевое значение, тогда у вас может быть следующий синтаксис, это позволит вам использовать ngFor* для итерации по объектам, а не по массивам.
<div *ngFor = "let question of boilerplate | keyValue">
{{ question.key }} - {{ question.value }}
</div>
Затем вы можете сделать то же самое для вложенных объектов внутри, пока не отобразятся правильные данные. Это поддерживается не во всех версиях Angular, но определенно нормально в 8.
Если у вас есть объекты с ключом в виде числа, я бы попытался преобразовать его в массив, который поможет вам сделать это немного проще. Позволяет использовать традиционные *ngFor
Вместе с предложением Максима Кузьмина это сработало: <div *ngFor = "let question of boilerplate[section.key].content | keyvalue"> {{question.value}} </div> Спасибо.
рад, что вы решили свою проблему, пожалуйста, не стесняйтесь редактировать это в этом ответе
Ответ от schoolcoder отличный, я просто хотел бы опубликовать еще один пример для людей в будущем с той же проблемой.
У меня есть блок объектов, который содержит список транзакций, и я хочу показать его на своей странице, используя два * ngFor
Класс блочной модели:
export class Block {
hash: string;
previousBlockHash: string;
transactions: Transaction[]; <<<<<<<<<<<
merkleRoot: string;
tries: number;
timestamp: number;
}
Класс модели транзакции
export class Transaction {
hash: string;
text: string;
senderHash: string;
signature: string;
timestamp: number;
}
Как я показываю это на своей странице:
Blocks:
<div class = "container">
<ul class = "list-group">
<li class = "list-group-item" *ngFor = "let block of blocks | keyvalue">
Hash: {{blocks[block.key].hash}}<br>
Previous block hash: {{blocks[block.key].previousBlockHash}}<br>
Merkle root: {{blocks[block.key].merkleRoot}}<br>
Tries: {{blocks[block.key].tries}}<br>
Timestamp: {{blocks[block.key].timestamp}}<br>
Transactions in this block:
<ul class = "list-group">
<li class = "list-group-item" *ngFor = "let transaction of blocks[block.key].transactions">
{{[block.key]}}<br>
Hash: {{transaction.hash}}<br>
Text: {{transaction.text}}<br>
SenderHash: {{transaction.senderHash}}<br>
Signature: {{transaction.signature}}<br>
Timestamp: {{transaction.timestamp}}
</li>
</ul>
</li>
</ul>
</div>
Это то, что я в итоге сделал, спасибо!