Angular2:如何正确绑定到嵌套数据?
Angular2: How do you properly bind to nested data?
我有一个组件,我将用作 shell 来加载多项选择题。到目前为止,组件的设置方式如下
组件
import { Component } from '@angular/core';
export class Answers{
id: string;
answer: string;
}
const answers: Answers[] = [
{
id: 'exp01q',
answer: 'Its fine as is.'
},
{
id: 'exp02q',
answer: 'I want to make minor adjustments.'
},
{
id: 'exp03q',
answer: 'I want to change my image'
},
{
id: 'exp04q',
answer: 'Ive never wanted to use a particular image until now.'
}
];
@Component({
moduleId: module.id,
selector: 'multi-radio-btn',
templateUrl: 'multi-rad-btn.component.html',
styleUrls: ['multi-rad-btn.component.css']
})
export class MultiRadioBtnShell {
question = 'How do you feel about your current image?';
id = 'exp-img-q';
name = 'exp-ques1';
ans = answers;
}
HTML 模板
<h3>radio button shell</h3>
<div class="row justify-content-center">
<fieldset [attr.id]='id' class="card col-8 justify-content-center">
<label class="ques-title">
{{question}}
</label>
<div class="row answer-row-section justify-content-center">
<div *ngFor="let answers of ans" class="col col-12 answer-row justify-content-center">
<div class="col justify-content-center">
<input type="radio"
[attr.id]="answers.id"
[attr.name]="name"
[attr.value]="answers.answer" hidden />
<label [attr.for]="answers.id" class="col ques-ans-title" style="background-color: #4b73a0;">
{{answers.answer}}
</label>
</div>
</div>
</div>
</fieldset>
</div>
现在设置成这样的原因是因为我一开始尝试的方法不起作用,所以我去了英雄之旅教程,了解他们如何加载所有英雄。问题来自未定义的答案。因此,我按照他们制作英雄的方式来操纵这部分,只是为了做一些我能够遵循的事情,只是为了确保我了解事物加载的机制。
我最初尝试这样做的方法是这样的
// I had this right above the component
export class ExpQ{
question: string;
id: string;
name: string;
answers:[
{
id: string;
answer: string;
}
]
}
// I had this in the component's class
export const expq: ExpQ[] = [
{
question: 'How do you feel about your current image?',
id: 'exp-img-q',
name: 'exp-ques1',
answers:[
{
id: 'exp01q',
answer: 'Its fine as is.'
},
{
id: 'exp02q',
answer: 'I want to make minor adjustments.'
},
{
id: 'exp03q',
answer: 'I want to change my image'
},
{
id: 'exp04q',
answer: 'Ive never wanted to use a particular image until now.'
}
]
}
]
我在 html 中用
调用它
{{expq.question}}, {{expq.name}}, {{expq.answers.id}}, {{expq.answers.answer}}, etc.
起初只是加载问题它工作正常,但当我到达 answers:
部分时它开始崩溃。我遇到了这个 https://scotch.io/tutorials/using-angular-2s-model-driven-forms-with-formgroup-and-formcontrol 并看到 addresses:
部分的语法与我需要构建数据的方式几乎相同。所以我把所有东西都重做了,让它看起来很像。我仍然没有运气让它工作。
最终,我将使用 @input
和 @output
以及我遇到的其他一些技巧通过父组件发送问题。但在我什至考虑之前,我需要了解如何将数据全部放入一个源中,以便它正确读取嵌套的数据位。我遇到的所有示例都是简单的单层数据位,因此我不确定我需要使用的语法。我怎样才能完成这项工作?
您可以像这样定义您的模型:
export interface Answer {
id: string;
answer: string;
}
export interface Question {
id: string;
name: string;
question: string;
answers: Answer[];
}
然后您的组件可以对此进行测试
question1: Question = {
id: 'q1',
name: 'q1',
question: 'Does TypeScript rule?',
answers: [
{ id: 'a1', answer: 'Yes' },
{ id: 'a2', answer: 'Of Course' },
{ id: 'a3', answer: 'Duh' }
]
};
当然,名称不必相同,但我认为这可以让您更好地了解如何为嵌套数据建模。
然后要显示它,您需要迭代嵌套结构。查找 *ngFor 指令。在这种情况下,您将需要遍历您的答案。例如:
<div *ngFor="let answer of question1.answers">
{{answer.id}} - {{answer.answer}}
</div>
需要展平对象,
参数:
对象:至少 n>0 个数组 JSON 个对象(不管是循环的)
目标:{}
路径:“”
注意:确保传入的对象数组至少为 n>0
flatten(objects, target, path) {
let me = this;
let retArray = [];
for(let x=0; x < objects.length; x++) {
let object = objects[x];
path = path || '';
target={};
target = me.flattenHelper(object, target, path);
retArray.push(target);
}
return retArray;}
..
flattenHelper(object, target, path){
let me = this;
Object.keys(object).forEach(function (key) {
console.log("key : "+ key + " : object : " + (object[key] && typeof object[key] === 'object') + " path : " + path);
if (object[key] && typeof object[key] === 'object') {
me.flattenHelper(object[key], target, path + key);
}
target[path + key] = object[key];
console.log(target);
});
return target;}
我有一个组件,我将用作 shell 来加载多项选择题。到目前为止,组件的设置方式如下
组件
import { Component } from '@angular/core';
export class Answers{
id: string;
answer: string;
}
const answers: Answers[] = [
{
id: 'exp01q',
answer: 'Its fine as is.'
},
{
id: 'exp02q',
answer: 'I want to make minor adjustments.'
},
{
id: 'exp03q',
answer: 'I want to change my image'
},
{
id: 'exp04q',
answer: 'Ive never wanted to use a particular image until now.'
}
];
@Component({
moduleId: module.id,
selector: 'multi-radio-btn',
templateUrl: 'multi-rad-btn.component.html',
styleUrls: ['multi-rad-btn.component.css']
})
export class MultiRadioBtnShell {
question = 'How do you feel about your current image?';
id = 'exp-img-q';
name = 'exp-ques1';
ans = answers;
}
HTML 模板
<h3>radio button shell</h3>
<div class="row justify-content-center">
<fieldset [attr.id]='id' class="card col-8 justify-content-center">
<label class="ques-title">
{{question}}
</label>
<div class="row answer-row-section justify-content-center">
<div *ngFor="let answers of ans" class="col col-12 answer-row justify-content-center">
<div class="col justify-content-center">
<input type="radio"
[attr.id]="answers.id"
[attr.name]="name"
[attr.value]="answers.answer" hidden />
<label [attr.for]="answers.id" class="col ques-ans-title" style="background-color: #4b73a0;">
{{answers.answer}}
</label>
</div>
</div>
</div>
</fieldset>
</div>
现在设置成这样的原因是因为我一开始尝试的方法不起作用,所以我去了英雄之旅教程,了解他们如何加载所有英雄。问题来自未定义的答案。因此,我按照他们制作英雄的方式来操纵这部分,只是为了做一些我能够遵循的事情,只是为了确保我了解事物加载的机制。
我最初尝试这样做的方法是这样的
// I had this right above the component
export class ExpQ{
question: string;
id: string;
name: string;
answers:[
{
id: string;
answer: string;
}
]
}
// I had this in the component's class
export const expq: ExpQ[] = [
{
question: 'How do you feel about your current image?',
id: 'exp-img-q',
name: 'exp-ques1',
answers:[
{
id: 'exp01q',
answer: 'Its fine as is.'
},
{
id: 'exp02q',
answer: 'I want to make minor adjustments.'
},
{
id: 'exp03q',
answer: 'I want to change my image'
},
{
id: 'exp04q',
answer: 'Ive never wanted to use a particular image until now.'
}
]
}
]
我在 html 中用
调用它{{expq.question}}, {{expq.name}}, {{expq.answers.id}}, {{expq.answers.answer}}, etc.
起初只是加载问题它工作正常,但当我到达 answers:
部分时它开始崩溃。我遇到了这个 https://scotch.io/tutorials/using-angular-2s-model-driven-forms-with-formgroup-and-formcontrol 并看到 addresses:
部分的语法与我需要构建数据的方式几乎相同。所以我把所有东西都重做了,让它看起来很像。我仍然没有运气让它工作。
最终,我将使用 @input
和 @output
以及我遇到的其他一些技巧通过父组件发送问题。但在我什至考虑之前,我需要了解如何将数据全部放入一个源中,以便它正确读取嵌套的数据位。我遇到的所有示例都是简单的单层数据位,因此我不确定我需要使用的语法。我怎样才能完成这项工作?
您可以像这样定义您的模型:
export interface Answer {
id: string;
answer: string;
}
export interface Question {
id: string;
name: string;
question: string;
answers: Answer[];
}
然后您的组件可以对此进行测试
question1: Question = {
id: 'q1',
name: 'q1',
question: 'Does TypeScript rule?',
answers: [
{ id: 'a1', answer: 'Yes' },
{ id: 'a2', answer: 'Of Course' },
{ id: 'a3', answer: 'Duh' }
]
};
当然,名称不必相同,但我认为这可以让您更好地了解如何为嵌套数据建模。
然后要显示它,您需要迭代嵌套结构。查找 *ngFor 指令。在这种情况下,您将需要遍历您的答案。例如:
<div *ngFor="let answer of question1.answers">
{{answer.id}} - {{answer.answer}}
</div>
需要展平对象,
参数:
对象:至少 n>0 个数组 JSON 个对象(不管是循环的) 目标:{}
路径:“”
注意:确保传入的对象数组至少为 n>0
flatten(objects, target, path) {
let me = this;
let retArray = [];
for(let x=0; x < objects.length; x++) {
let object = objects[x];
path = path || '';
target={};
target = me.flattenHelper(object, target, path);
retArray.push(target);
}
return retArray;}
..
flattenHelper(object, target, path){
let me = this;
Object.keys(object).forEach(function (key) {
console.log("key : "+ key + " : object : " + (object[key] && typeof object[key] === 'object') + " path : " + path);
if (object[key] && typeof object[key] === 'object') {
me.flattenHelper(object[key], target, path + key);
}
target[path + key] = object[key];
console.log(target);
});
return target;}