Angular 2方法在ngOnInit中通过单击按钮调用时返回不同的结果



我正在使用Angular 2 CLI构建一个网站,该页面是一个反应式表单,我创建了一个名为addQuestion()的方法,该方法在ngOnInit中调用。当它以这种方式运行时,它会按照我的意愿运行,添加一个带有答案数组的Question对象。当我通过按下按钮运行相同的方法时,它会在页面中添加一个Question对象,而不附带答案数组。我已经突出显示了工作不正常的行。

有人能解释一下我做错了什么吗?

更清楚地说,方法:

  1. 创建Question对象
  2. 然后创建4个答案对象,并将它们添加到Question对象中
  3. 然后将Question对象推入Questions数组

当我从ngOnIt运行此方法时,它会创建带有嵌入答案数组(填充有4个答案)的完整Question对象,并将其添加到问题数组中。

当我从一个按钮运行该方法时,按下页面本身:

<a href="" (click)="addQuestion()">Add Question</a>

它添加了Question对象,但带有一个空的answers数组。我在下面我认为错误发生的地方加了一个箭头。我在这行之前添加了一些控制台日志命令,它们显示它们的答案被正确添加,但在这次推送之后,它们就像消失了一样。我认为这是某种范围错误,但我是一个初级开发人员,无法独自解决。

export class QuestionListComponent implements OnInit {
@Input('quizForm')
public quizForm: FormGroup;
@Input('questions')
public questions: Question[];
nextId: number;
constructor(private cd: ChangeDetectorRef) { }
// <previous> 1. Create FormGroup quizForm
// <previous> 2. Add Quiz controls to FormGroup (via toFormGroup)
// 3. Add questions FormArray to FormGroup
// 4. Add first Question to questions FormArray
ngOnInit() {
console.log('Initializing question list', this.questions);
this.nextId = 1;
this.quizForm.addControl('questions', new FormArray([]));
this.addQuestion();
}
//_.uniqueId(),
private getNextId(): number{
return this.nextId++
}
addQuestion() {
const question: Question = {
id: this.getNextId(),
title: 'My Question',
instructions: 'Instructions here',
time: 30000,
answerId: 1,
answers: []
};
for(var i=1;i<=4;i++){
const a: Answer = {
id: i,
data: "Answer #" + i.toString(),
type: "TEXT"
}
question.answers.push(a);
}
console.log("question equals=" + question);
console.log("question answer 2 data = " + question.answers[1].data);
this.questions.push(question); <--- This is the error line of code
this.cd.detectChanges();
return false;
}

编辑:一条附加信息。我的代码基于这个优秀的ReactiveForms教程,在他的代码中,他使用了接口而不是类。我在接口方面没有太多经验,所以我想知道这对我的情况是否重要。以下是接口:

export interface Question {
id: number;
title: string;
instructions: string;  
time: number;  // The number of Milliseconds the question will be shown
answerId: number; //the array id of the correct answer
answers?: Answer[];
}
export interface Answer {
id: number;
data: string;
type: string; // to be enum AnswerType in the future
}

我会试着把它们换成类,看看这是否能解决我的问题。这是HTML代码,我怀疑问题可能也在这里。

<div [formGroup]="quizForm">
<div formArrayName="questions">
<div *ngFor="let question of questions; let idx=index">
Question {{question.id}} (<a href="" (click)="removeQuestion(idx)">Remove</a>)
<app-question-form [questions]="quizForm.controls.questions" [question]="question">
</app-question-form>
</div>
<a href="" (click)="addQuestion()">Add Question</a>
</div>
</div>

编辑:更多线索。这个SO问题询问了一个类似的问题,该问题的答案是"您将无法在组件二的承包商内部访问此输入,只能在其"ngOnInit"内部访问。请参阅此以供参考"。如果这是真的,这是我第一次听说它。我认为这就是Input decorator/annotation的原因,就是在组件之间传递对象。

您是否尝试过在变量中使用关键字let而不是const?

无论你定义的类型是Question[],你的questions都是null或未定义的,所以它调用null,然后不包括push的方法,所以抛出错误。

@Input('questions')
public questions: Question[] = [];

我发现了这个错误,我仍然承认我很困惑。在子组件中,我传递的对象已损坏。该对象是一个Question对象,它包含一组答案对象,该列表称为答案。该对象是使用@Input()装饰器传递给子对象的。您可以看到上面列出的界面。

我的错误是我的答案数组被破坏或重置,所以当我从父组件调用该方法时,它是空的。那么问题出在哪里呢?在子组件ngOnInit()中,我还创建了另一个名为answers的变量。这是代码行。。。

this.questionForm.addControl('answers', new FormArray([]));

这是一个FormArray对象,与答案无关,答案是我传递的对象的属性。。。但是在我的代码中有了这一行,我的对象就被破坏了。。。答案数组被删除。当我将FormArray的名称更改为"answers"以外的名称时,它可以正常工作。

这是Angular中的一个错误吗?

最新更新