为什么将代码放入 setTimeout 中可以使 Angular 正常工作?

Cod*_*ein 1 javascript settimeout angular

我一直在尝试在 Angular 5 中创建一个简单的指令,但遇到了困难。我最近发现,将我的代码添加到setTimeout函数中可以使其按我的预期工作。在这种情况下,我希望表单显示为“ yolo

我不完全明白为什么。我知道这与 Angular 引导的方式有关,但我不明白为什么会这样 - 特别是为什么构造函数中的代码被丢弃(毕竟,构造函数的意义何在?)

请在下面找到相关代码的简化副本:

使用setTimeout

没有设置超时

@Directive({
  selector: '[formControlName][phone]',
  host: {
    '(ngModelChange)': 'onInputChange($event)'
  }
})
export class PhoneMask {

  constructor(public model: NgControl) {
    // with setTimeout
    setTimeout(() => {  
      this.model.valueAccessor.writeValue('yolo');
    });

    // without setTimeout
    // this.model.valueAccessor.writeValue('yolo');

  }

}

@Component({
  selector: 'my-app',
  providers: [],
  template: `
  <form [formGroup]="form">
    <input type="text" phone formControlName="phone"> 
  </form>
  `,
  directives: [PhoneMask]
})
export class App {
  constructor(fb:FormBuilder) {
    this.form=fb.group({
      phone:['']
    })
  }
}

@NgModule({
  imports: [ BrowserModule, FormsModule, ReactiveFormsModule ],
  declarations: [ App, PhoneMask ],
  bootstrap: [ App ]
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

bul*_*rce 6

当您将代码放入 setTimeout 中时,您实际上是将其从当前调用堆栈中取出,一旦整个调用堆栈被执行,事件循环将选择您的代码并将其放在新的调用堆栈的顶部,然后执行将开始。当调用堆栈完成时,您可能会遇到术语“tick”,那就是“tick”。在您的情况下,setTimeout 基本上是 0ms,但代码已从当前堆栈中删除,因此其他一切都完成,然后您的代码运行,修改属性,并且角度变化检测器检测到变化。