Bidirectional data binding on a component input property

前端 未结 4 1846
名媛妹妹
名媛妹妹 2021-02-19 07:24

I am trying to make something work on angular2 and I am unable to find something about this behavior.

I have an application that implements a custom component like this

相关标签:
4条回答
  • 2021-02-19 07:58

    I'll combine @pixelbits and @Günter Zöchbauer answers and comments to make a clear answer on my question if someone in the future is searching for this.

    To make bidirectional data binding works on custom variables you need to creates your component based on the following.

    MyComp.ts file :

    import {Component,Input,Output,EventEmitter} from 'angular2/core'
    @Component({
      selector:'my-comp',
      templateUrl:`<input type="text" style="text-align:center;"
         [ngModel]="inputText" (ngModelChange)="inputText=$event;inputTextChange.emit($event);">`
    })
    
    export class MyComp{
      @Input() inputText : string;
      @Output() inputTextChange = new  EventEmitter();
    }
    

    MyApp.ts file:

    import {Component} from 'angular2/core'
    import {MyComp} from './MyComp'
    
    @Component({
      selector:'my-app',
      templateUrl:`<h1>Bidirectionnal Binding test </h1>
        <my-comp [(inputText)]="testString"></my-comp><p>
        <b>My Test String :</b> {{testString}}</p>`,
      directives:[MyComp]
    })
    
    export class MyApp{
      testString : string;
      constructor(){
        this.testString = "This is a test string";
      }
    }
    

    There the bidirectional data binding to the inputText variable works correctly. You can comment the answer for a more beautiful or simpler way to implement this code.

    0 讨论(0)
  • 2021-02-19 08:06

    This is explained in the Template Syntax doc, in the Two-Way Binding with NgModel section:

    <input [(ngModel)]="currentHero.firstName">

    Internally, Angular maps the term, ngModel, to an ngModel input property and an ngModelChange output property. That’s a specific example of a more general pattern in which it matches [(x)] to an x input property for Property Binding and an xChange output property for Event Binding.

    We can write our own two-way binding directive/component that follows this pattern if we're ever in the mood to do so.

    Note also that [(x)] is just syntactic sugar for a property binding and an event binding:

    [x]="someParentProperty" (xChange)="someParentProperty=$event"
    

    In your case, you want

    <my-comp [(inputText)]="testString"></my-comp>
    

    so your component must have an inputText input property and an inputTextChange output property (which is an EventEmitter).

    export class MyComp {
      @Input()  inputText: string;
      @Output() inputTextChange: EventEmitter<string> = new EventEmitter();
    }
    

    To notify the parent of changes, whenever your component changes the value of inputText, emit an event:

    inputTextChange.emit(newValue);
    

    In your scenario, the MyComp component binds input property inputText using the [(x)] format to ngModel, so you used event binding (ngModelChange) to be notified of changes, and in that event handler you notified the parent component of the change.

    In other scenarios where ngModel isn't used, the important thing is to emit() an event whenever the value of property inputText changes in the MyComp component.

    0 讨论(0)
  • 2021-02-19 08:25

    Your Plunker already contains the EventEmitter. The @Output() annotation is missing. To change the value call inputTextChanged.emit(newValue) (this also changes the value on inputText)

    0 讨论(0)
  • 2021-02-19 08:25

    What I do is use a property, so when I change the data the change is emitted automatically

    private _data: AnyType;
    @Input()  get data(): AnyType{
        return this._data;
    }
    set data(value: AnyType) {
        this._data = value;
        this.dataChange.emit(this._data);
    }
    @Output() dataChange: EventEmitter<AnyType> = new EventEmitter();
    

    In html you will bind the property using [(data)]

    <comp [(data)]="getData()"></comp>
    
    0 讨论(0)
提交回复
热议问题