当在ngOnInit中按下单击按钮时,Angular 2方法返回不同的结果

时间:2017-11-02 01:42:14

标签: javascript arrays angular typescript

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

有人可以解释我做错了吗?

更清楚的是,方法:

  1. 创建一个问题对象
  2. 然后创建4个答案对象并将其添加到Question对象
  3. 然后将Question对象推送到Questions数组
  4. 当我从ngOnIt运行此方法时,它使用嵌入的答案数组(填充4个答案)创建完整的Question对象,并将其添加到问题数组中。

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

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

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

    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;
      }
    

    编辑:另外一条信息。我将我的代码基于excellent Reactive Forms tutorial,并且在他的代码中他使用了接口而不是类。我没有很多接口经验,所以我想知道这对我的情况是否重要。这是接口:

    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>
    

    编辑:更多线索。 This SO question询问类似的问题,该问题的答案是“你将无法在Component 2的承包商中访问此输入,只能在其”ngOnInit“内。请参阅此参考”。如果这是真的,这是我第一次听说过它。我认为这就是输入装饰器/注释的原因,就是在组件之间传递对象。

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

无论您定义questions类型,Question[]为空或未定义,因此调用null然后不包含push的方法,因此错误是抛出。

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

答案 2 :(得分:0)

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

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

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

这是一个FormArray对象,与答案无关,答案是我传递的对象的属性......但是在我的代码中有这一行,我的对象被破坏了......并且答案数组被擦除了。当我将FormArray的名称更改为&#39; answers&#39;之外的其他名称时它工作正常。

这是Angular中的错误吗?