Angular 2 - 为什么不能注销输入值

时间:2018-02-14 15:08:58

标签: angular angular2-directives

我觉得我必须在这里遗漏一些东西,并想知道是否有更好的方法来做到这一点。

我有一个指令,它基本上将一个类添加到输入字段的父元素。在加载时我需要检查输入字段是否有值,你认为这很简单......

我现在使用了一些不同的选项,其中包括ngOnInitAfterContentInitAfterViewInit。但对于下面我还在AfterContentInit

ngAfterContentInit() {
  console.log(this.el.nativeElement); // Element Object "Value is not empty if you look inside the object."
  console.log(this.el.nativeElement.value); // = ''

  setTimeout(() => {
    console.log(this.el.nativeElement.value); // = 'The Value!'
  }, 1000);

  this.activeStateCheck(this.el.nativeElement);
}

activeStateCheck(element) {
  if (element.value !== '') {
    element.parentElement.classList.add('active');
    return true;
  }
}

我应该指出所有选项都会给出相同的结果。

第一个控制台注销一个空字符串,第二个控制台注销实际字符串。在这种情况下,它是'大巡回赛'。

我的问题是如何在不使用setTimeout的情况下执行此操作?

在您可以记录该值之前,似乎必须等待数据加载到页面上。但是我的印象是OnInit意味着等待这个完成?

我想找到更好的解决方案的原因是因为如果页面加载时间超过一秒,那么控制台日志将输出一个空字符串,因此不是一个完整的解决方案。

这是被调用指令的一个例子。请注意appPlaceholder属性:

<fieldset class="form__placeholder">
    <input type="text" 
            id="lastName" 
            formControlName="lastName" 
            appPlaceholder>
    <label for="lastName"
           class="form__placeholder--label">
      Lastname:
    </label>
</fieldset>

4 个答案:

答案 0 :(得分:4)

根据您所说的,我不确定您是否需要自定义指令。如果您确实想要将“活动”类添加到非空输入的父级,则只需执行

即可
<div [ngClass]={'active': groupForm.get('name').value !== ''}>
  <input formControlName="lastName">
</div>

您甚至可以省略!== '',因为空字符串是假的。

如果您出于其他原因绝对需要指令,则可以将formControlName视为指令的输入@Input() formControlName;,但如果您这样做,则还需要传递{ {1}} in。但是,更改父项的行为似乎很麻烦,尤其是像你正在做的直接DOM操作(改为使用HostBinding)。我可能建议将父/输入组合配对到新组件中。

答案 1 :(得分:1)

当你说页面加载时间超过1秒时,是否意味着它从服务中加载数据以填写表单?

您可以尝试使用ng-container包装表单,并仅在数据加载完成时呈现表单。

这样的东西
<ng-container *ngIf="finishLoading">

    // ......

    <fieldset class="form__placeholder">
        <input type="text" 
                id="lastName" 
                formControlName="lastName" 
                appPlaceholder>
        <label for="lastName"
               class="form__placeholder--label">
          Lastname:
        </label>
    </fieldset>

    // ......

</ng-container>

并在组件类中,在数据加载完成后将finishLoading设置为true

this.finishLoading = true;

希望这有帮助。

答案 2 :(得分:0)

您可以像这样使用表单valueChanges:

this.myForm.get('lastName').valueChanges.subscribe(val => {
     console.log(val);
     this.activeStateCheck(val);
});  

您可以在组件,OnInt或AfterViewInit中的任何位置使用它。

查看此文章了解更多详情:

https://alligator.io/angular/reactive-forms-valuechanges/

答案 3 :(得分:0)

要确保值到达时,您必须订阅HTMLInputElement输入事件发射器。有了这个,你永远不会有竞争条件左右。我认为它适合您的目的。

ngOnInit() {  
  fromEvent(this.el.nativeElement, 'input').subscribe((event) => activeStateCheck(event.target.value);
}

activeStateCheck(value) {
  if (value !== '') {
    this.el.element.parentElement.classList.add('active');
    return true;
  }
}

希望这有帮助。