简体   繁体   中英

2-Way Binding a Property of a Component in Angular 2

I am trying to make a directive, where one set of Input/Output fields are linked to be like a 2 way binding as per with [(ngModel)].

Here's a simplified version of what I'm trying to do:

@Component({
    selector: "template-for-inputbox",
    template: 
    `
     <div><label>{{Label}}</label>
         <input [(ngModel)]="Value"/>
     </div>
    `
})
export class TemplateForInputBoxDirective{
    @Input() DataValue:any;
    @Output() DataChanged:EventEmitter<any> = new EventEmitter();
    get Value(){
        return this.Data;
    }
    set Value(tValue){
         //Check some things about the new value then...
         this.DataChanged.emit(tValue);
    }
}

While reading http://victorsavkin.com/post/119943127151/angular-2-template-syntax I tried creating a directive to split things out:

@Directive({
    selector: "[Data]",
    host: {
        "[DataValue]": "Data",
        "(DataChanged)":"DataChanging.next($event)"
    }
})
export class DataBinding {
    @Input() Data: any;
    @Output() DataChanging: EventEmitter<any> = new EventEmitter();
    ngOnInit() {
        let vData = this.Data;
    }
}

Where I would then use it like this:

<template-for-inputbox [(Data)]="SomeObject.Value"></template-for-inputbox>

As opposed to:

<template-for-inputbox [DataValue]="SomeObject.Value"
                       (DataChanged)="SomeObject.Value = $event">
</template-for-inputbox>

The objects and number of times this comes up makes the bottom version just a mess.

But so far only the bottom version is working, the values I'm dealing with in the top version don't do anything.

In order to do two way binding, the output variable name should be, inputVarName + 'Change' . So, in your example, it will be DataChange and the input variable Data .

export class TemplateForInputBoxDirective{
    @Input() Data:any;
    @Output() DataChange:EventEmitter<any> = new EventEmitter();
    get Value(){
        return this.Data;
    }
    set Value(tValue){
         //Check some things about the new value then...
         this.DataChange.emit(tValue);
    }
}

Then you can use it like:

<template-for-inputbox [(Data)]="SomeObject.Value"></template-for-inputbox>

Just a note , the convention is to use PascalCase for class names and camelCase for variable names. It's so confusing to read the variables PascalCased

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM