I see in primeng components the use something like ngModel (two-way data binding) style for some property like this
[(selection)]="selectedItem";
it 's look like
@Input() selection;
@Output() selection:EventEmitter<any> = new EventEmitter<any>();
how I can implement something like this and is it possible to do for more than single property like
<component-a [(selection)]="selectedItem" [(data)]="selectedData"></component-a>
Angular docs
<app-sizer
[(size)]="fontSizePx">
</app-sizer>
The two-way binding syntax is really just syntactic sugar for a
property binding and an event binding. Angular desugars the
binding into this:
<app-sizer
[size]="fontSizePx"
(sizeChange)="fontSizePx=$event">
</app-sizer>
To create two-way binding for property selection
use:
@Input() selection;
// You have to follow this convention (For Output property)
// i.e. <propertyName><Change> like selectionChange
@Output() selectionChange:EventEmitter<any> = new EventEmitter<any>();
And to change selection in component as shown below:
changeSelection(newSelection)
{
this.selection = newSelection;
// emit change event to parent component
this.selectionChange.emit(this.selection);
}
https://angular.io/guide/template-syntax#two-way-binding
The [(x)]
syntax is easy to demonstrate when the element has a settable property called x and a corresponding event named xChange
.
This means, you only need a corresponding selectionChange
method on your child component. Hence, if you want the banana-in-a-box binding for your property selection
of ParentComponent
into ChildComponent
, follow these steps:
Include the following in your ChildComponent
:
@Input() selection;
@Output() selectionChange = new EventEmitter<any>();
In your ParentComponent
template:
<child [(selection)]="selection">
In summary, if your property name is x
, you only need to name its corresponding EventEmitter to xChange
and do the banana-in-a-box syntax for the child component [(x)] = "parentProperty"
and Angular takes care of the rest.
In your child component you have to implement two-way binding interface like this:
private _selection: any;
get selection(): any {
return this._selection;
}
@Input()
set selection(value: any) {
if(this._selection === value) {
return;
}
this._selection = value;
this.selectionChange.emit(this._selection);
}
@Output()
selectionChange = new EventEmitter<any>();
It's mandatory to name @Output
filed by adding propertyNameChange
to @Input
name.
So you can use it in your parent component temlate like this:
<mycomponent [(selection)]="fieldInParentComponent"></mycomponent>
In your child component (component-a) you need an @output
@Output() change:EventEmitter = new EventEmitter();
and then you notify parent component about a changed value by
change.emit(newValue);
See also Angular2: https://stackoverflow.com/a/33220997/3710630