Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/431.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Angular 2中创建自定义窗体控件_Javascript_Angularjs_Forms_Angular - Fatal编程技术网

Javascript 在Angular 2中创建自定义窗体控件

Javascript 在Angular 2中创建自定义窗体控件,javascript,angularjs,forms,angular,Javascript,Angularjs,Forms,Angular,我正在尝试为元素创建一个自定义表单控件组件(我意识到这不是创建自定义表单控件的最具创新性的用途,但这只是为了测试目的)。我将跟随教程@ 我的目标是禁用submit按钮,直到从组件中选择了一个值,但我认为我没有正确连接自定义表单控件,因为当我选择不同的值时,该值不会更改,验证也不会工作(验证=仅自定义组件上的requiredHTML属性) 到目前为止,请参阅下面的内容。或者,您可以从以下网址获得plunker 谢谢 主要部件 import {Component, NgModule} from '@

我正在尝试为
元素创建一个自定义表单控件组件(我意识到这不是创建自定义表单控件的最具创新性的用途,但这只是为了测试目的)。我将跟随教程@

我的目标是禁用submit按钮,直到从
组件中选择了一个值,但我认为我没有正确连接自定义表单控件,因为当我选择不同的值时,该值不会更改,验证也不会工作(验证=仅自定义组件上的
required
HTML属性)

到目前为止,请参阅下面的内容。或者,您可以从以下网址获得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() {}
}
从'@angular/core'导入{Component,NgModule};
从“@angular/platform browser”导入{BrowserModule};
从“/select box.component”导入{SelectBoxComponent};
从“@angular/forms”导入{FormsModule};
@组成部分({
选择器:“我的应用程序”,
模板:`
你好{{name}

提交
{{form.value | json}} `, }) 导出类应用程序{ 名称:字符串; someValue:any=1; 日志(str){ console.log(str); } } @NGD模块({ 导入:[BrowserModule,FormsModule], 声明:[应用程序,SelectBoxComponent], 引导:[应用程序] }) 导出类AppModule{}
选择框组件

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() {}
}
import{Component,forwardRef,Input}来自“@angular/core”;
从“@angular/forms”导入{SelectControlValueAccessor,NG_VALUE_ACCESSOR};
@组成部分({
选择器:“选择框”,
模板:`
1.
2.
`,
供应商:[
{
提供:NG_值访问器,
useExisting:forwardRef(()=>SelectBoxComponent),
多:是的,
}
],
})
导出类SelectBoxComponent实现SelectControlValueAccessor{
@输入模式:任意;
一次更改(值){
该模型=值;
这是一个变化(值);
}
writeValue(值:任意){
如果(值)this.value=值;
}
传播变化=((uu0:any)=>{};
注册变更(fn){
这一变化=fn;
}
寄存器(){}
}

这里有一个组件修复程序:

在select组件中,有一些错误

  • 您没有正确绑定模型。请添加getter/setter,以便您可以跟踪更改并使用
    this.\u onChangeCallback
    this.\u onTouchedCallback();
  • 您需要注册
    registerOnTouched
    事件并触发它。这样,您的模型可能会变得
    dirty
    ,并且您的表单可以检测更改是否有效/无效

  • 内联回答您的问题所需的所有内容,不要发送给我们在外面寻找它们,谢谢。@gdoron当然,只是将其添加到问题中什么是
    window[“onChanged”]=this.onChanged.bind(this)
    应该是什么意思?你知道这意味着页面上不能有两个,对吧?我注意到你使用了
    ControlValueAccessor
    ,而不是我最初使用的
    SelectControlValueAccessor
    。我的印象是每种类型的输入都应该与其对应的值访问器一起使用,但这可能是错误的或错误的有一些我不知道的警告?