web-dev-qa-db-ja.com

Angular2双方向データバインディング

私はAngular2に双方向のデータバインディングがないことを知っていますが、Angular1.xからの双方向のデータバインディング動作を模倣する方法はありますか?

21

注-ng-modelバインディングの答えを下にスクロールします

ゾーン内のバインディングを更新するために内部ダイジェストリスナーティック(ダイジェストに類似)を呼び出すだけで、実際にそれを行うことができます。そのために(keyup)イベントを追加するだけです。同様に、コンポーネント設定のproperties辞書でディレクティブバインディングを使用することもできます。

例:-

<input #label (keyup)> 
<!-- variable #label represented as the element itself and accessible as property on controller instance 
 You can even bind keyup to a function or another another function and pass value from the label property-->

表示:

<p>{{label.value}}</P>

親コンポーネントには、テキストボックスとラベルがあります。

import { Component, bootstrap} from '@angular/core';
import {Display} from 'display';

@Component({
  selector: 'my-app',
  template: `<p><b>Parent Component:</b><p><input #label (keyup) (change)="handleChange(label.value)">
        <p>{{label.value}}</P> <display [text]="label"></display></p></p>`,
  directives: [Display]
})

class MainComponent {
  label: any;

  constructor() {

  }

  handleChange(label){
    this.label = label;
    console.log(this.label);
  }

}

子コンポーネントにも表示します:

@Component({
  selector: 'edit',
  template: `<p><b>Child Component:</b></p>{{text.value}}`
})

export class Edit {
    @Input() text:any;
}

デモ



更新-双方向バインディングのng-model

Angular2はデフォルトで1回限りのバインドですが、ngModel sugarが導入され、双方向のバインディングを実現しています。それにより、たとえば次のことができます。

<input ngControl="name" [(ngModel)]="name">

ここで、角括弧([..])の使用は、イベントバインディングのプロパティバインディングと丸括弧((..))を示しています。基本的にng-modelを使用すると、両方のバインディングngModelがイベントになります。舞台裏では、監視可能なイベント(EventEmitterを使用)を作成して、バインドされた要素のvalueの変更を追跡し、バインドされたプロパティをそれぞれ更新します。例えば:-

FormDirectivesを含める:

 import {FORM_DIRECTIVES} from '@angular/common';

そしてフォームで

   <form (ngSubmit)="onSubmit()" let-f="form">
      <input ngControl="name" [(ngModel)]="name">
      <button>Click me and check console</button>
   </form>

形なし

  <input  [(ngModel)]="name">
  <button (click)="onSubmit()">Click me and check console</button>

もう必要ない ビュー注釈にformDirectives依存関係を含めます。

@Component({
  template: .....,
  directives: [FORM_DIRECTIVES]
})

デモ

また、ng-modelイベントを作成し、それがどのように機能するかによって、angular2の双方向バインディングの Nice write up from Victor Savkin も読んでください。

19
PSL

次の構文を使用してngModelを使用することで、これを簡単に行うことができます。

<input [(ngModel)]="myProp" />

角括弧と丸括弧の組み合わせは、「双方向バインディング」を意味します。

プランクをご覧ください こちら

15
JDTLH9

はい、angular2には双方向バインディングがあります。こちらをご覧ください: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ngModel

では、カスタムコンポーネントでそれを使用する方法は?

私がしたいことはこれです:

private currentSelectedItem: MachineItem;
@Output() selectedItemChange: EventEmitter<MachineItem> = new EventEmitter<MachineItem>();

@Input() set selectedItem(machineItem: MachineItem) {
    this.currentSelectedItem = machineItem;
    this.selectedItemChange.emit(machineItem); 
}

get selectedItem(): MachineItem {
    return this.currentSelectedItem; 
}

そして、それを次のように使用します

<admin-item-list [(selectedItem)]="selectedItem"></admin-item-list>

実際に変更された場所で新しい値を発行することもできます。しかし、私はセッターメソッドでそれをグロバリーに行うことは非常に便利であり、例えば気にする必要はありません。ビューに直接バインドするとき。

11
Mario Eis

これを行うには、入力フィールドのイベントにアタッチし、この例のように内部値を更新します。

http://plnkr.co/edit/lOFzuWtUMq1hCnrm9tGA?p=preview

ラベルthis.labelおよびイベントオブジェクトを予期するコールバックchangeLabelを保持する内部属性を持つコンポーネントを作成します

@Component({
  selector: 'app',
  templateUrl: 'bound.html'
})
class App {
  label: string;
  constructor() {
    this.label = 'default label'
  }
  changeLabel(event) {
    this.label = event.target.value;
  }
}

bootstrap(App);

テンプレートを作成し、コールバックを適切なイベントに添付します(keypressイベントに添付できますが、タイムアウトが必要になる場合があります。簡単にするためにchangeイベントに添付します(更新を確認するには、入力をタブで移動する必要があるかもしれません)。

<label for="myinput">{{label}}</label>
<input id="myinput" type="text"/>
<p></p>You can change the label above by typing something below</p>
<label for="labeltext">New Label Text</label>
<input type="text" id="labeltext" (change)="changeLabel($event)"/>
6
unobf

Angular2をだまして双方向バインディングにする別の方法があります。プロパティではなくオブジェクトをコンポーネントに渡します。一方向バインディングを介してオブジェクトを渡す場合、そのプロパティはすべて双方向バインドされます。オブジェクトを知る必要があるため、コンポーネントの汎用性は低下しますが、多くの場合、依然として有用です。

次のようなコンポーネントがあります。

import { Component, Input }    from "@angular/core";
import { NgSwitch, NgSwitchWhen, NgSwitchDefault }    from "@angular/common";

export class Movie
{
    public Title: string;
    public Rating: number;
    public Seen: boolean;
}

@Component
({
    selector: "hh-image-checkbox",
    template: `
        <div [ngSwitch]="movie.Seen"> 
            <div *ngSwitchWhen="true">
                <img src="/Content/res/CheckTrue.png" (click)="onClick()"> 
            </div> 
            <div *ngSwitchDefault> 
                <img src="/Content/res/CheckFalse.png" (click)="onClick()"> 
            </div> 
        </div>
        `,
    directives: [NgSwitch, NgSwitchWhen, NgSwitchDefault]
})

export class ImageCheckboxComponent
{
    @Input() movie: Movie;

    public onClick()
    {
        this.movie.Seen = !this.movie.Seen;
    }
}

次のように呼び出されます。

<hh-image-checkbox [movie]="movie"></hh-image-checkbox>

ムービーオブジェクト自体は一方向にバインドされていますが、そのプロパティはすべて双方向バインドに使用できます。

5
hholtij

これは、Angular2 2.0.0-beta.17に従って、一方向、双方向、およびイベント駆動型のアプローチを実際に実行する簡単なプランカーです。

http://plnkr.co/eXZMo

双方向のイベントとプロパティ

<input [(ngModel)]="name" />

一方向性

<input [value]="name" />

イベント駆動

<input (input)="name=$event.target.value">

Dig Angular docs for more

2
Davut Gürbüz

ドキュメントから:

双方向バインディング([(...)]

多くの場合、データプロパティを表示し、ユーザーが変更を加えたときにそのプロパティを更新する必要があります。

特定の要素プロパティの設定と要素変更イベントのリッスンの組み合わせをとる要素側。

Angularは、この目的のための特別な双方向データバインディング構文[(x)]を提供します。 [(x)]構文は、プロパティバインディングのブラケット、[x]、イベントバインディングの括弧付き、(x)

[( )] = BANANA IN A BOX

ボックス内のバナナを視覚化して、括弧が括弧内に収まることを思い出してください。

詳細については、

1
georgeawg

簡単です、これを試してください。

<input [(ngModel)]="property" placeholder="property Value"/>
<h1>{{property}}</h1>
0
Jalasem