【问题标题】:Lifecycle Hook for after ngModel is loaded加载 ngModel 后的生命周期挂钩
【发布时间】:2017-01-18 10:17:57
【问题描述】:

我有一个函数需要在我的组件中设置this.value 后运行。我尝试使用生命周期挂钩ngAfterContentInit(),但此时this.value 要么为空,要么为空字符串。

我正在引用我的组件,例如:

<add-select name="address" [options]="knownAddresses" [(ngModel)]="user.address"></add-select>

我的组件看起来像

const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => AddSelect),
    multi: true
};

@Component({
  selector: 'add-select',
  templateUrl: 'build/components/add-select/add-select.html',
  providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class AddSelect implements ControlValueAccessor {
  @Input() options: any[];

  // * NEED THIS TO RUN AFTER this.value IS CURRENT WHICH IS PASSED IN VIA ngModel
  private syncModelAndOptions() {
        if (this.options && this.value) {
            const modelOption = _.find(this.options, option => {
                return item == this.value || (option._id && this.value._id && option._id === this.value._id);
            });

            if (modelOption) {
                this.value = modelOption;
            } else {
                this.options.push(this.value);
            }
        }
    }

  //get accessor
  get value(): any {
    ...
  };

  //set accessor including call the onchange callback
  set value(v: any) {
    ...
  }

  //From ControlValueAccessor interface
  writeValue(value: any) {
    ...
  }

  //From ControlValueAccessor interface
  registerOnChange(fn: any) {
    ...
  }

  //From ControlValueAccessor interface
  registerOnTouched(fn: any) {
    ...
  }

【问题讨论】:

    标签: angular typescript ionic2


    【解决方案1】:

    当 ngModel 具有实际值时,您可以使用 AfterViewChecked 生命周期来获取它。如果你真的想使用生命周期钩子。

    https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#afterview

    但是...您应该使用 ngModelChange,因为它是一个 ngModel 事件。

    https://angular.io/docs/ts/latest/guide/forms.html(搜索 ngModelChange)

    【讨论】:

    • 我当然没有固定在生命周期钩子上,我只是认为我应该这样做。如果我使用生命周期事件,它会起作用,但如果可能的话,我宁愿做一些更有效率的事情。我只需要在 this.value 实际定义后运行一次 fn。即使我传入了一个值,直到稍后它仍然是未定义的。生命周期挂钩是完成我需要的唯一方法吗?
    • 你检查过 ngModelChange 了吗?它应该在每次模型更改时运行。
    • 我试过了。加载初始值时不会触发。
    【解决方案2】:

    也许以这种方式使用 NgModel 会对您有所帮助。在你的组件内部:

      import { NgModel } from '@angular/forms';
    
        /*...*/
    
      constructor(ngModel: NgModel) {
    
        ngModel.valueChanges.subscribe(() => {
          console.log('ngModel set')
        });
      }
    

    【讨论】:

      【解决方案3】:

      您实现ControlValueAccessor 接口的原因是您的组件可以很好地与Angular 表单(模板驱动和反应式)配合使用。

      在模板驱动的表单中(基本上是在您使用ngModel 时),对ngModel 的更新最终会触发对ControlValueAccessor.writeValue 的调用,它应该知道如何更新底层表单控件。

      因此,一旦框架设置了this.value(即ngModel),就可以从writeValue 中调用它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-24
        • 2021-09-19
        • 1970-01-01
        • 2017-07-12
        • 1970-01-01
        • 2015-12-19
        相关资源
        最近更新 更多