【问题标题】:Why can I access form's control inside setTimout but not outside?为什么我可以在 setTimeout 内部访问表单控件,但不能在外部访问?
【发布时间】:2018-02-25 18:59:49
【问题描述】:

我还是 Angular 的新手,我发现 form 和 setTimeout 很奇怪...... 当我尝试在 OnInit 上的 setTimeout 中获取 TD 的表单控件时,它可以工作,但在 setTimeout 函数之外却不能。 setTimeout 的超时设置为 0 毫秒。你知道是什么导致了这种行为吗?我不想将它包装在 setTimeout 函数中...

模板:

<form #f="ngForm">
  <div class="form-group">
    <label for="email">Email address:</label>
    <input type="text"
           name="email"
           id="email"
           [(ngModel)]="model.email"
           required
           email>
  </div>
  <div class="form-group">
    <label for="subscription">Select subscription:</label>
    <select name="subscription"
            id="subscription"
            [(ngModel)]="model.subscription">
      <option value="basic">Basic</option>
      <option value="advanced">Advanced</option>
      <option value="pro">Pro</option>
    </select>
  </div>
  <div class="form-group">
    <label for="password">Password:</label>
    <input type="text"
           name="password"
           id="password"
           [(ngModel)]="model.password"
           required>
  </div>
  <button type="submit">Submit</button>
</form>

组件:

import { Component, ViewChild, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  @ViewChild('f') f: NgForm;

  model = {
    email: '',
    subscription: 'advanced',
    password: ''
  };

  constructor() {}

  ngOnInit(): void {
    setTimeout(() => {
      console.log(this.f.form.get('subscription')); // Works
    }, 0);
    console.log(this.f.form.get('subscription')); // Doesn't work
  }
}

感谢您的回答 + 抱歉我的英语不好。

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    您无法在setTimeout 之外访问表单的原因是在调用ngOnInit 时,尚未生成表单。在 setTimeout 内部运行的代码在不同的刻度中运行,到那时,表单已创建。

    来自documentation

    ngOnInit 在第一次检查指令的数据绑定属性之后,并且在检查其任何子项之前立即调用。当指令被实例化时,它只被调用一次。

    在调用 ngAfterViewInit 生命周期挂钩之前,该表单不可用。请参阅here for all the lifecycle hooks 以及如何使用它们。

    【讨论】:

    • AfterViewInit 钩子也有同样的问题。
    • 嗯……这太令人惊讶了。你可以试试ngAfterContentInit 钩子吗?
    • 那也行不通。我什至尝试创建新的 Angular 5.2.0 项目,但也没有成功。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    相关资源
    最近更新 更多