Je sais que Angular2 n'a pas de liaison de données bidirectionnelle, mais existe-t-il un moyen d'imiter le comportement de liaison de données bidirectionnelle d'Angular1.x?
Remarque - faites défiler la réponse pour la liaison ng-model
Vous pouvez en fait le faire, juste que vous devez invoquer un tick interne de changelistener (similaire à digest) pour mettre à jour la liaison dans la zone, vous pouvez simplement ajouter un (keyup)
événement pour cela. De même, vous pouvez également utiliser des liaisons de directive avec properties
dictionnaire de paramètres de composant.
Exemple:-
<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-->
Afficher comme:
<p>{{label.value}}</P>
Le composant parent a une zone de texte et une étiquette.
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);
}
}
Maintenant, l'afficher également dans le composant enfant:
@Component({
selector: 'edit',
template: `<p><b>Child Component:</b></p>{{text.value}}`
})
export class Edit {
@Input() text:any;
}
Mise à jour - modèle ng pour la liaison bidirectionnelle
Bien que Angular2 soit lié une seule fois par défaut, ngModel
sugar a été introduit pour obtenir une liaison bidirectionnelle. Avec cela, vous pouvez par exemple:
<input ngControl="name" [(ngModel)]="name">
Voici l'utilisation des crochets ([..]
) suggère la liaison de propriété et les crochets ((..)
) pour la liaison d'événement. Fondamentalement, lorsque vous utilisez ng-model
, vous activez les deux liaisons ngModel
est plutôt un événement. Dans les coulisses, il crée un événement observable (avec EventEmitter
) pour suivre les changements value
dans l'élément lié et mettre à jour la propriété liée respectivement. Par exemple:-
Inclure le formulaire
import {FORM_DIRECTIVES} from '@angular/common';
et avec forme
<form (ngSubmit)="onSubmit()" let-f="form">
<input ngControl="name" [(ngModel)]="name">
<button>Click me and check console</button>
</form>
sans forme
<input [(ngModel)]="name">
<button (click)="onSubmit()">Click me and check console</button>
plus nécessaire inclure la dépendance formDirectives dans l'annotation de vue.
@Component({ template: ....., directives: [FORM_DIRECTIVES] })
Lisez également le Belle écriture de Victor Savkin sur la liaison bidirectionnelle dans angular2 en créant l'événement ng-model et comment il fonctionne.
Vous pouvez maintenant simplement le faire en utilisant ngModel en utilisant la syntaxe suivante:
<input [(ngModel)]="myProp" />
La combinaison des crochets carrés et ronds signifie "liaison bidirectionnelle".
S'il vous plaît voir le plunk ici
Oui, il y a une liaison bidirectionnelle dans angular2. Voir ici: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ngModel
Alors, comment l'utiliser dans des composants personnalisés?
Ce que j'aime faire, c'est quelque chose comme ceci:
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;
}
Et utilisez-le comme
<admin-item-list [(selectedItem)]="selectedItem"></admin-item-list>
Vous pouvez également émettre la nouvelle valeur là où elle est réellement modifiée. Mais je trouve cela très pratique de faire cette gloabaly dans une méthode setter et je n'ai pas à me soucier par exemple quand je le lie directement à ma vue.
Vous pouvez le faire en attachant aux événements sur le champ de saisie et en mettant à jour la valeur interne comme cela se fait dans cet exemple:
http://plnkr.co/edit/lOFzuWtUMq1hCnrm9tGA?p=preview
Créez un composant possédant un attribut interne contenant le label this.label
et un rappel changeLabel
qui attend un objet événement
@Component({
selector: 'app',
templateUrl: 'bound.html'
})
class App {
label: string;
constructor() {
this.label = 'default label'
}
changeLabel(event) {
this.label = event.target.value;
}
}
bootstrap(App);
Créez votre modèle et attachez le rappel à l'événement approprié (vous pouvez l'attacher à l'événement keypress
mais vous pourriez avoir besoin d'un délai d'attente. Je l'ai attaché à l'événement change
pour plus de simplicité (ce qui signifie que vous devrez peut-être taper l'entrée pour voir la mise à jour).
<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)"/>
Il existe une autre façon de tromper Angular2 en liaison bidirectionnelle. Ne passez pas une propriété mais un objet dans le composant. Si vous passez un objet via une liaison à sens unique, toutes ses propriétés sont en fait à double sens. Cela rend le composant moins polyvalent car il a besoin de connaître l'objet, mais dans de nombreux cas, il est toujours utile.
J'ai un composant qui ressemble à ceci:
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;
}
}
Il est invoqué comme ceci:
<hh-image-checkbox [movie]="movie"></hh-image-checkbox>
L'objet vidéo lui-même est lié à sens unique, mais toutes ses propriétés peuvent être utilisées pour la liaison bidirectionnelle.
Voici un plongeur simple qui démontre les approches unidirectionnelles, bidirectionnelles et événementielles en action selon Angular2 2.0.0-beta.17
Événement bidirectionnel et propriété
<input [(ngModel)]="name" />
Propriété à sens unique
<input [value]="name" />
Événementiel
<input (input)="name=$event.target.value">
Nous pouvons creuser Angular docs for more
Depuis les documents:
Liaison bidirectionnelle (
[(...)]
)Vous souhaitez souvent afficher à la fois une propriété de données et la mettre à jour lorsque l'utilisateur apporte des modifications.
Du côté de l'élément, il faut combiner la définition d'une propriété d'élément spécifique et l'écoute d'un événement de changement d'élément.
Angular propose à cet effet une syntaxe de liaison de données bidirectionnelle spéciale,
[(x)]
. La syntaxe[(x)]
combine les crochets de la liaison de propriété,[x]
, avec les parenthèses de la liaison d'événement,(x)
.[( )] = BANANA IN A BOX
Visualisez une banane dans une boîte pour vous souvenir que les parenthèses vont à l'intérieur des crochets.
Pour plus d'informations, voir
C'est simple, essayez ceci;
<input [(ngModel)]="property" placeholder="property Value"/>
<h1>{{property}}</h1>