【问题标题】:Angular elements as native form control in reactive formAngular 元素作为反应形式的原生表单控件
【发布时间】:2019-05-18 10:48:59
【问题描述】:

我正在尝试将表单控件导出为 Angular 元素(Web 组件)并将其用作本机输入元素,以便它可以与角反应式表单或与本机 html 输入一起使用的类似库一起使用。

波纹管代码在模块中作为角度组件导出时有效。当我将其导出为 Web 组件并尝试以反应形式使用它时遇到问题。

此代码是使用 Angular 7.1 框架编写的。

组件模板

<input ngDefaultControl value="value" />

组件代码:

@Component({
  selector: 'cns-text-input',
  templateUrl: './text-input.component.html',
  styleUrls: ['./text-input.component.scss'],
  providers: [ {
    provide: NG_VALUE_ACCESSOR,
    useExisting:  forwardRef(() => TextInputComponent),
    multi: true
  }]
})
export class TextInputComponent implements ControlValueAccessor,     AfterViewInit {

  @ViewChild(DefaultValueAccessor) valueAccessor:     DefaultValueAccessor;

  public ngAfterViewInit() {
    console.log('value accessor', this.valueAccessor);
    console.log(this);
  }

  public writeValue(obj: any): void {
    this.valueAccessor.writeValue(obj);
  }
  public registerOnChange(fn: any): void {
    this.valueAccessor.registerOnChange(fn);
  }
  public registerOnTouched(fn: any): void {
    this.valueAccessor.registerOnTouched(fn);
  }
  public setDisabledState?(isDisabled: boolean): void {
    this.valueAccessor.setDisabledState(isDisabled);
  }

}

模块代码:

@NgModule({
  declarations: [TextInputComponent],
  imports: [FormsModule],
  // exports: [TextInputComponent],
  entryComponents: [TextInputComponent]
})
export class FormModule {
  constructor(private injector: Injector) {
    const textInputElement = createCustomElement(TextInputComponent, { 
      injector 
    });
    customElements.define('cns-text-input', textInputElement);
  }

  ngDoBootstrap() {}
}

用法示例:

// app component html
<form [formGroup]="group">
  <cns-text-input formControlName="text"></cns-text-input>
</form>

// app component

export class AppComponent {
  title = 'web-components-lib-poc';

  public group: FormGroup;

  constructor(private fb: FormBuilder) {
    this.group = this.fb.group({ text: 'my vlaue' });
    this.group.valueChanges.subscribe(val => console.log(val));
  }
}

上面的代码导致错误:ERROR 错误:表单控件没有值访问器,名称为:'text'

有没有更好的方法来构造这个组件,使其表现得更像原生输入?

【问题讨论】:

    标签: angular angular-elements


    【解决方案1】:

    我找到了答案。在 Angular 应用程序中使用非本地输入组件时,ngDefaultControl 将有助于解决值访问器错误。

    所以代码是:

    <cns-text-input formControlName="text" ngDefaultControl></cns-text-input>
    

    ** 编辑 **

    这也适用于其他 web 组件,例如 Polymer Elements Paper Input

    【讨论】:

    • 能否请您在 Stack-blitz 中添加您的代码。我有相同的代码,但它不适合我!
    猜你喜欢
    • 2017-11-27
    • 1970-01-01
    • 2018-05-31
    • 1970-01-01
    • 2022-08-06
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多