angular - 如何在 Stencil 中创建自定义输入元素以与 Angular/Ionic 一起使用?

标签 angular ionic-framework angular-reactive-forms stenciljs

我很头疼想弄清楚这个问题。我想创建一个可以在我的 Angular/Ionic 应用程序中使用的自定义输入元素。我如何将 Angular 属性与这些自定义元素一起使用,例如 FormControlName。

<my-custom-stencil-input type="text" formControlName="firstName"></my-custom-stencil-input>

我有下面的代码,但是当我尝试使用 FormControlName 时它显示错误。

import { Component, h, Prop } from '@stencil/core';

@Component({
  tag: 'ba-text-input-one',
  styleUrl: './text-input-1.component.css',
  scoped: true,
})
export class TextInputOne {
  @Prop({reflect: true}) type: string;
  @Prop({reflect: true}) placeholder: string;
  @Prop({reflect: true}) formControlName: string;


  render() {
    return (
      <div id="cmp">
        <div id="icon-area">
          <slot name="icon"></slot>
        </div>
        <input id="input-field" formControlName={this.formControlName} type={this.type} />
      </div>
    );
  }
}

Stencil 上的文档没有详细说明如何解决这个问题。

本质上,我想在 Angular 响应式表单中使用我自己的自定义 Stencil 输入元素。

最佳答案

我遇到了同样的问题,但我找到了解决方案:

首先,您不必在模板项目中创建 formControlName。

import { Component, Event, EventEmitter, h, Prop } from "@stencil/core";

@Component({
    tag: 'my-custom-stencil-input',
    styleUrl: 'input.css',
    shadow: true
})

export class Input {
    @Prop({reflect: true, mutable: true}) label: string;
    @Prop({reflect: true, mutable: true}) value: string;
    @Prop() type = 'text'; 
    @Event() valueChanged: EventEmitter<string>;
    private onInputChangeValue(event: Event) {
        this.value = (event.target as HTMLInputElement).value;
        this.valueChanged.emit(this.value);
    }
    render() {
        return (
            <div>
                <label> {this.label} </label>
                <input type= {this.type} value= {this.value} onInput= {this.onInputChangeValue.bind(this)}/>
            </div>
        )
    }
}

然后,在 Angular 项目中,您必须创建一个指令,因为您需要实现 ControlValueAccessor,它充当 Angular 表单 API 和 DOM 中 native 元素之间的桥梁。

import { Directive, forwardRef, HostBinding, HostListener } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Directive({
  selector: '[appAccessor]',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => FormDirective),
      multi: true,
    },
  ],
})

export class FormDirective implements ControlValueAccessor {
  @HostBinding('value') hostValue: any;

  lastValue: any;
  private onChange = (value: any) => {};
  private onTouched = () => {};

  writeValue(value: any) {
    this.hostValue = this.lastValue = value == null ? '' : value;
  }

  registerOnChange(fn: (value: any) => void) {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void) {
    this.onTouched = fn;
  }


  @HostListener('valueChanged', ['$event.detail'])
  _handleInputEvent(value: any) {
    if (JSON.stringify(value) !== JSON.stringify(this.lastValue)) {
      this.lastValue = value;
      this.onChange(value);
      this.onTouched();
    }
  }
}

最后,以 react 形式使用自定义元素(在本例中为输入):

<form [formGroup]="myFormGroup">
      <my-custom-stencil-input label="Any label" appAccessor formControlName="control1" ></my-custom-stencil-input>
</form>

就是这样。

关于angular - 如何在 Stencil 中创建自定义输入元素以与 Angular/Ionic 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63909749/

相关文章:

angularjs - 使用 ionic/angular 应用程序发布 facebook 帖子

amazon-web-services - 如何订阅 DynamoDB 中的更改

Angular2 - 从元素中删除禁用的属性

Angular 获取 HTTP 请求的响应大小

node.js - Angular 6 和 Node Js AWS S3 文件上传进度条

angular - 没有'new'就不能调用类构造函数

javascript - ionic 2 : How to render multiple image card using ngFor

Angular 5 表单重复输入值

angular - 在 Angular 中动态地将控件添加到 FormGroup

angular - 保存 Angular 2 *ngFor 循环的最后一个值