Angular2 liaison de données bidirectionnelle
Je sais Qu'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?
7 réponses
Remarque - faites défiler vers le bas la réponse pour le gn-liaison du modèle
Vous pouvez réellement le faire, juste que vous devez appeler la tique interne de changelistener (similaire à digest) pour mettre à jour la liaison dans la zone, vous pouvez simplement ajouter un événement (keyup)
pour cela. De même, vous pouvez également utiliser des liaisons de directive avec properties
dictionnaire des paramètres des composants.
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 un é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);
}
}
L'affiche maintenant dans le composant enfant:
@Component({
selector: 'edit',
template: `<p><b>Child Component:</b></p>{{text.value}}`
})
export class Edit {
@Input() text:any;
}
Mise à Jour - ng-model pour 2 voies de liaison
Bien Qu'Angular2 soit lié une fois par défaut, ngModel
sugar a été introduit pour obtenir une liaison à 2 voies. Avec cela, vous pourriez faire par exemple:
<input ngControl="name" [(ngModel)]="name">
Ici, l'utilisation de crochets ([..]
) suggère la liaison de propriétés et les crochets ronds ((..)
) pour la liaison d'événements. Fondamentalement quand vous utilisez ng-model
, vous activez les deux liaisons ngModel
est plus 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 formDirectives:
import {FORM_DIRECTIVES} from '@angular/common';
Et avec la 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 en vue annotation.
@Component({
template: .....,
directives: [FORM_DIRECTIVES]
})
Lisez aussi la belle écriture de Victor Savkin sur la liaison bidirectionnelle dans angular2 en créant l'événement ng-model et son fonctionnement.
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 les composants personnalisés?
Ce que j'aime faire est quelque chose 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 l'utiliser comme
<admin-item-list [(selectedItem)]="selectedItem"></admin-item-list>
Vous pouvez également émettre la nouvelle valeur où elle est réellement modifiée. Mais je trouve très pratique de faire cela gloabaly dans une méthode setter et ne pas avoir à déranger par exemple quand je le lie directement à mon vue.
Vous pouvez le faire en attachant aux événements sur le champ de saisie et en mettant à jour la valeur interne comme cela est fait dans cet exemple:
Http://plnkr.co/edit/lOFzuWtUMq1hCnrm9tGA?p=preview
Créer un composant qui a un attribut interne qui contient l'étiquette this.label
et un rappel changeLabel
qui attend un objet d'é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 timeouts. Je l'ai attaché à l'événement change
pour plus de simplicité (ce qui signifie que vous devrez peut-être supprimer 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 unidirectionnelle, toutes ses propriétés sont en fait liées dans les deux sens. Il rend le composant moins polyvalent que les besoins 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 film lui-même est lié à un sens mais tous ses les propriétés peuvent être utilisées pour la liaison bidirectionnelle.
Voici un simple plunker qui démontre des approches à Sens Unique, 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énement piloté
<input (input)="name=$event.target.value">
Nous pouvons creuser des documents angulaires pour plus
C'est simple, essayez ceci;
<input [(ngModel)]="property" placeholder="property Value"/>
<h1>{{property}}</h1>