Issue
First I've created a User class:
export class User {
name: string;
email: string;
}
Then I've got my CoreComponent which uses the FormInputComponent as well as creating a public user from the User class:
import {Component} from 'angular2/core';
import {FormInputComponent} from '../form-controls/form-input/form-input.component';
import {User} from '../core/user';
@Component({
selector: 'core-app',
templateUrl: './app/assets/scripts/modules/core/core.component.html',
styleUrls: ['./app/assets/scripts/modules/core/core.component.css'],
directives: [FormInputComponent]
})
export class CoreComponent {
public user: User = {
name: '',
email: ''
}
}
Then I've created an input component, which is a re-useable input component that will take a model value as an input and when changes are made export the new value so that CoreComponent can update the model with the new value:
import {Component, Input, Output, EventEmitter, DoCheck} from 'angular2/core';
@Component({
selector: 'form-input',
templateUrl: './app/assets/scripts/modules/form-controls/form-input/form-input.component.html',
styleUrls: ['./app/assets/scripts/modules/form-controls/form-input/form-input.component.css'],
inputs: [
'model',
'type',
'alt',
'placeholder',
'name',
'label'
]
})
export class FormInputComponent implements DoCheck {
@Input() model: string;
@Output() modelExport: EventEmitter = new EventEmitter();
ngDoCheck() {
this.modelExport.next(this.model);
}
}
The CoreComponent's template uses two FormInputComponents and passes user.name and user.email as the input for them:
<form-input [model]="user.name" type="text" name="test" placeholder="This is a test" alt="A test input" label="Name"></form-input>
<form-input [model]="user.email" type="email" name="test" placeholder="This is a test" alt="A test input" label="Email"></form-input>
<pre>{{user.name}}</pre>
The FormInputComponent template:
<div>
<label attr.for="{{name}}">{{label}}</label>
<input [(ngModel)]="model" type="{{type}}" placeholder="{{placeholder}}" alt="{{alt}}" id="{{name}}">
</div>
<pre>{{model}}</pre>
Now the problem is that I can only see the changes from the pre element that lies inside the FormInputComponent template, but the parent, CoreComponent's pre element remains unchanged.
I looked at this question which is in the ballpark of what I want to achieve but not quite since using a service for just returning a value up the hierarchy seems like overkill and a bit messy if you have multiple FormInputComponents on the same page.
So my question is simple, how can I pass a model to FormInputComponent and letting it return a new value whenever the value changes so that the public user in CoreComponent changes automatically?
Solution
To be able to use two way binding short when using your component you need to readme your output property to modelChange:
export class FormInputComponent implements DoCheck {
@Input() model: string;
@Output() modelChange: EventEmitter = new EventEmitter();
ngDoCheck() {
this.modelChange.next(this.model);
}
}
And use it this way:
<form-input [(model)]="user.name" type="text" name="test" placeholder="This is a test" alt="A test input" label="Name"></form-input>
<form-input [(model)]="user.email" type="email" name="test" placeholder="This is a test" alt="A test input" label="Email"></form-input>
<pre>{{user.name}}</pre>
Answered By - Thierry Templier
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.