javascript - 在 Angular 2 中创建自定义表单控件

标签 javascript angularjs forms angular

我正在尝试为 <select> 创建自定义表单控件组件元素(我意识到这不是创建自定义表单控件的最具创新性的用途,但这只是为了测试目的)。我正在关注教程 @ http://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html .

我的目标是禁用提交按钮,直到从 <select-box> 中选择了一个值。组件,但我认为我没有正确连接自定义表单控件,因为当我选择不同的值时值不会改变,验证也不起作用(验证 = 只是自定义组件上的 required HTML 属性) .

请参阅下文,了解我目前所掌握的内容。或者,可以在 http://plnkr.co/edit/TAxDyb8sHg158dXmyfwr?p=preview 找到一个 plunker。 .

谢谢!

主要成分

import {Component, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {SelectBoxComponent} from "./select-box.component";
import {FormsModule} from "@angular/forms";

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <form #form="ngForm" (ngSubmit)="log(form.value)">
        <select-box name="someValue" [ngModel]="someValue" required></select-box>
        <br>
        <button type="submit" [disabled]="!form.valid">Submit</button>
      </form>
      <br>
      {{ form.value | json }}
    </div>
  `,
})
export class App {
  name:string;
  someValue: any = 1;

  log(str) {
    console.log(str);
  }
}

@NgModule({
  imports: [ BrowserModule, FormsModule ],
  declarations: [ App, SelectBoxComponent ],
  bootstrap: [ App ]
})
export class AppModule {}

选择框组件

import { Component, forwardRef, Input } from "@angular/core";
import { SelectControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";

@Component({
  selector: "select-box",
  template: `
    <select onchange="onChanged(event.target.value)" [ngModel]="ngModel">
      <option disabled selected value></option>
      <option value="1">1</option>
      <option value="2">2</option>
    </select>
  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => SelectBoxComponent),
      multi: true,
    }
  ],
})

export class SelectBoxComponent implements SelectControlValueAccessor {
  @Input() ngModel: any;

  onChanged(value) {
    this.ngModel = value;
    this.propagateChange(value);
  }

  writeValue(value: any) {
    if (value) this.value = value;
  }

  propagateChange = (_: any) => {};

  registerOnChange(fn) {
    this.propagateChange = fn;
  }

  registerOnTouched() {}
}

最佳答案

此处为您的组件修复:http://plnkr.co/edit/69SGnjYGBWhC4tEezc1G?p=preview

<select [(ngModel)]="selectValue">
  <option disabled selected value></option>
  <option value="1">1</option>
  <option value="2">2</option>
</select>

.ts 中:

export class SelectBoxComponent implements ControlValueAccessor {
  private _selectValue: any = '';
  private _onTouchedCallback: () => {};
  private _onChangeCallback: (_:any) => {};

  hasValue: boolean;

  get selectValue(): any {
    return this._selectValue;
  }
  set selectValue(value: any) {
    if (value !== this._selectValue) {
      this._selectValue = value;
      this._onChangeCallback(value);
    }

    this.hasValue = (value != null && value.length > 0)
    
     this._onTouchedCallback();

  }


  
  //From ControlValueAccessor interface
  writeValue(value: any) {
    this._selectValue = value;
  }

  //From ControlValueAccessor interface
  registerOnChange(fn: any) {
    this._onChangeCallback = fn;
  }

  //From ControlValueAccessor interface
  registerOnTouched(fn: any) {
    this._onTouchedCallback = fn;
  }
}

在您的选择组件中,有一些错误。

  1. 您没有正确绑定(bind)模型。添加 getter/setter,以便您可以跟踪更改并使用 this._onChangeCallbackthis._onTouchedCallback();
  2. 通知它
  3. 您需要注册registerOnTouched 事件并触发它。这样,您的模型可以变得,并且您的表单可以检测更改是否有效。

关于javascript - 在 Angular 2 中创建自定义表单控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40009149/

相关文章:

javascript - 如何在javascript中格式化 float ?

javascript - AngularJS 如何将 $watch 变量与 $http 一起使用?

javascript - 使用 selenium 和 ngWebDriver 访问动态 ng-repeat

c# - 线程启动期间的竞争条件?

java - 取消选中框

javascript - 在 DropDownlist 中滚动自定义

javascript - javascript 中的变量未使用innerHTML 显示在html 页面上

javascript - 通过 ids 数组过滤 Angular 数据

c# - 如何对列表框数据中的表单进行分类

javascript - jquery:当 'hover' 在 '.myBox' 上解除绑定(bind)时执行某些操作?