如何将 ngModel 与表单内的自定义控件一起使用? [英] How to use ngModel with a custom control inside a form?

查看:22
本文介绍了如何将 ngModel 与表单内的自定义控件一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个用于处理选择框的组件,现在当我在提交表单后将其放入表单标签时,选择的结果不会显示在控制台中.

我的代码有什么问题?我该如何解决这个问题?

  • testOption:是我传递的对象数组,使用 @Input 抛出选择框.

这里是选择框组件:

import { Component, OnInit, Input } from '@angular/core';@成分({选择器:'输入选择',模板:`<div class="field-select"><span><icon name="select-arrow" size="10"></icon></span><select name="{{name}}" class="field"><option value="0" disabled selected>{{label}}</option><option *ngFor="let option of options" [ngValue]="option.value">{{option.name}}</option></选择>

`})导出类 InputSelectComponent 实现 OnInit {@Input() 标签:字符串;@Input() 名称:字符串;@Input() 选项;//测试选项 = [//{value:'test',name:'test2'},//{value:'test',name:'test2'}//];构造函数(){}ngOnInit() {控制台日志(this.options);}}

在 html 中的使用:

表单 html:

<input class="field" name="name" ngModel type="text" placeholder="n1"><input-select label="b2" name="select2" [options]="testObject"></input-select><input class="field" name="building-type" type="text" ngModel placeholder="b3"></表单>

控制台日志:(没有选择框值)

Object {name: "test", building-type: "tset" }

解决方案

我想我现在知道你的问题了.

您想在自定义组件上实现 ControlValueAccessor 以在带有 ngModel 的表单内使用它!?

您的组件应如下所示:

@Component({选择器:'ng2-输入-选择',模板:`<div class="field-select"><select name="{{ name }}" class="field" [(ngModel)]="value" (ngModelChange)="_onChange($event)"><option value="" disabled selected>{{ label }}</option><option *ngFor="let option of options" [value]="option.value">{{ option.name }}</option></选择>

`,供应商: [{/* idk 为什么或这会做什么..但它有效!;) */提供:NG_VALUE_ACCESSOR,useExisting: forwardRef(() => SelectBoxComponent),多:真}]})导出类 SelectBoxComponent 实现 OnInit、ControlValueAccessor {@Input() 标签:字符串;@Input() 名称:字符串;@Input() 选项;@Input() 值:字符串 = '';//ControlValueAccessor 实现//====================================//如果在我们的组件中更改了值,则调用private _onChange = (_: any) =>{ };//如果输入被触摸"则调用 .. !私人_onTouched = () =>{ };//传入更改..公共写值(val:任何){this.value = val;}public registerOnChange(fn: (_: any) => void): void { this._onChange = fn;}public registerOnTouched(fn: () => void): void { this._onTouched = fn;}}

现场演示:https://plnkr.co/edit/imCJmCoJaeGQiUMcyBwz?p=preview

更新

在表单组件中使用变更检测:

<ng2-input-select ngModel (ngModelChange)="selectBoxChanged($event)" label="b2" name="select2" [options]="testObject"></ng2-input-select>

I created a component for handling select box, now when I put it in form tag after submitted form the result of the selection doesn't show up in console.

What's the problem with my code? how can I fix this?

  • testOption: is array of object I passed throw the select box with @Input.

here is select box component:

import { Component, OnInit, Input } from '@angular/core';

@Component({
    selector: 'input-select',
    template:`
      <div class="field-select">
        <span><icon name="select-arrow" size="10"></icon></span>
        <select name="{{name}}" class="field">
          <option value="0" disabled selected>{{label}}</option>
          <option *ngFor="let option of options" [ngValue]="option.value">{{option.name}}</option>
        </select>
      </div>
    `
})
export class InputSelectComponent implements OnInit {
    @Input() label: string;
    @Input() name: string;
    @Input() options;


    // testOptions = [
    //   {value:'test',name:'test2'},
    //   {value:'test',name:'test2'}
    // ];

    constructor() { }

    ngOnInit() {
      console.log(this.options);
     }

}

Usage in html:

<input-select label="test" name="select2" [options]="testOption"></input-select>

form html:

<form role="form" class="form" #f="ngForm" (ngSubmit)="onSubmit(f)">
    <input class="field" name="name" ngModel type="text" placeholder="n1">
    <input-select label="b2" name="select2" [options]="testObject"></input-select>
    <input class="field" name="building-type" type="text" ngModel placeholder="b3">
</form>

console log: (there is no select box value)

Object {name: "test", building-type: "tset" }

解决方案

I guess I got your problem now.

You want to implement ControlValueAccessor on your custom component to use it inside of a form with ngModel!?

Your component should look like this:

@Component({
   selector: 'ng2-input-select',
   template: `
      <div class="field-select">
        <select name="{{ name }}" class="field" [(ngModel)]="value" (ngModelChange)="_onChange($event)">
          <option value="" disabled selected>{{ label }}</option>
          <option *ngFor="let option of options" [value]="option.value">{{ option.name }}</option>
        </select>
      </div>
   `,
   providers: [
      { /* idk why or what this will do exactly.. but it works! ;) */
         provide: NG_VALUE_ACCESSOR,
         useExisting: forwardRef(() => SelectBoxComponent),
         multi: true
      }
   ]
})
export class SelectBoxComponent implements OnInit, ControlValueAccessor {
  @Input() label: string;
  @Input() name: string;
  @Input() options;
  @Input() value: string = '';

  // ControlValueAccessor implementation
  // ====================================

  // call if value was changed inside our component
  private _onChange = (_: any) => { };
  // call if input was "touched" .. !
  private _onTouched = () => { };

  // incoming change..
  public writeValue(val: any) {
    this.value = val;
  }

  public registerOnChange(fn: (_: any) => void): void { this._onChange = fn; }
  public registerOnTouched(fn: () => void): void { this._onTouched = fn; }
}

live-demo: https://plnkr.co/edit/imCJmCoJaeGQiUMcyBwz?p=preview

UPDATE

Using change detection in your form-component:

<ng2-input-select ngModel (ngModelChange)="selectBoxChanged($event)" label="b2" name="select2" [options]="testObject"></ng2-input-select>

这篇关于如何将 ngModel 与表单内的自定义控件一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆