Angular2 data binding for custom reusable component
Your myText is missing an @Output()
import {Component, Input, Output} from 'angular2/core';@Component({ selector: 'myText', template:`<label>{{someLabel}}</label> <input id=myId type="text" [ngModel]=bindModelData (ngModelChange)="updateData($event)"> `})export class MyTextComponent { @Input() myId : string; @Input() bindModelData: any; // note that this must be named as the input name + "Change" @Output() bindModelDataChange: any = new EventEmitter(); updateData(event) { this.bindModelData = event; this.bindModelDataChange.emit(event); }}
then you can use it like
import {Component} from 'angular2/core';import {MyTextComponent} from './MyTextComponent.component'@Component({ template:`<myText myId="id1" [(bindModelData)]="myString1"></myText> <myText myId="id2" [(bindModelData)]="myString2"></myText> `, directives:[MyTextComponent]})export class MyPageComponent{ myString1: string; myString2: string;}
I think this link will answer your question. http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel
1- My component (tmg.input.ts)
import { Component, forwardRef , Input} from '@angular/core';import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';const noop = () => {};export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TmgInput), multi: true};@Component({ template: `<md-input-container> <input mdInput id="id" name="name" placeholder="placeholder" [(ngModel)]="value" /> </md-input-container>`, selector: 'tmg-input', templateUrl: './tmg.input.html', providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]})export class TmgInput implements ControlValueAccessor { @Input() id: string; @Input() name: string; @Input() placeholder: string; //The internal data model private innerValue: any = ''; //Placeholders for the callbacks which are later providesd //by the Control Value Accessor private onTouchedCallback: () => void = noop; private onChangeCallback: (_: any) => void = noop; //get accessor get value(): any { return this.innerValue; }; //set accessor including call the onchange callback set value(v: any) { if (v !== this.innerValue) { this.innerValue = v; this.onChangeCallback(v); } } //Set touched on blur onBlur() { this.onTouchedCallback(); } //From ControlValueAccessor interface writeValue(value: any) { if (value !== this.innerValue) { this.innerValue = value; } } //From ControlValueAccessor interface registerOnChange(fn: any) { this.onChangeCallback = fn; } //From ControlValueAccessor interface registerOnTouched(fn: any) { this.onTouchedCallback = fn; }}
2- Then you can use it like this
<tmg-input [id]="'test'" [name]="'test'" [placeholder]="'Test'" [(ngModel)]="model.test"></tmg-input>