Décembre 2017
Volume 32, numéro 12
Cet article a fait l'objet d'une traduction automatique.
Le programmeur au travail - Comment être MEAN : Angular Forms aussi
Par Ted Neward | Décembre 2017
Bienvenue à nouveau, MEANers.
Dans la dernière colonne (msdn.com/magazine/mt845619), I, nous avons vu comment créer des formulaires avec angulaire, mais constructif oblige me admettez fait plutôt grave : J’ai vraiment à peine commencé à la surface des fonctionnalités d’angulaire concernant les formulaires de travail, des entrées, validation et bien plus encore. Par exemple, dans la version précédente d’angulaire (la version n’est pas-à-all-déroutant appelée AngularJS), il était possible de configurer « liaison bidirectionnelle » afin d’entrée du formulaire modifié un objet ECMAScript dans la mémoire dans le navigateur, ce qui signifiait que pourrait soucier de code objets de modèle et pas les champs d’entrée contenant les données.
Angulaire n’a pas encore abandonnée ce concept, mais il est nécessaire de vous montrer la syntaxe de liaison d’événement par rapport aux contrôles d’entrée avant que nous aurions pu y accéder. Maintenant que vous l’avez vu, vous pouvez commencer à Explorer les fonctionnalités de formulaire angulaire plus en détail.
SpeakerUI
Dans la dernière colonne, je vous a montré comment créer un composant appelé SpeakerEdit qui capture l’entrée d’utilisateur. Bah. Comment entièrement non-sélectionné-component orientée de me. Ce que vous devez voulez, s’il s’agit d’adopter une approche réellement orienté composant, est d’encapsuler les détails de l’affichage ou modification d’un intervenant. Autrement dit, vous voulez qu’un composant qui peut être transmis à un objet de modèle haut-parleur (pour modifier/mettre à jour ou suppression même), ID de l’orateur (ce qui signifie que le haut-parleur de modèle objet doit être extrait à partir du serveur) ou « non définie » (auquel cas vous demandez à l’utilisateur pour remplir un nouvel utilisateur objet de modèle), et « l’attitude » dans chaque cas. En bref, le composant doit connaissent déjà les éléments à afficher et comment l’afficher, basées uniquement sur le contenu (ou son manque) d’un objet haut-parleur correspondant.
Commençons par la génération d’un composant SpeakerUI. (J’ont tendance à utiliser « UI » comme suffixe, pour indiquer que cela est conçue comme un composant de l’interface utilisateur autonome autour du type de modèle de haut-parleurs. Certains lecteurs peuvent préférez « SpeakerDetail », car cela autorise le passage de la vue ou modifier des détails d’un modèle de haut-parleurs différents. Comme toujours, quelle que soit la convention vous choisissez, stick avec lui.) Il s’agit d’un secteur à l’aise pour vous à ce stade : « ng générer le composant SpeakerUI. »
Toutefois, je vais effectuer un ajout légère haut-parleur, afin de montrer la puissance du langage TypeScript lorsqu’il s’agit de l’interface utilisateur. Pour illustrer les différentes opérations, je vais de mentionner qu’entre la dernière colonne et ce, cliente de l’application a dit que les locuteurs ont un ou plusieurs sujets sur lesquels ils parlent, comme suit :
import { Upvote } from './upvote/upvote';
import { Subject } from './subject';
export class Speaker {
id: number;
firstName: string;
lastName: string;
votes: Upvote;
subjects: /*something*/[];
}
Le type d’objet doit être défini dans subject.ts, mais que vous disposez de deux options ici. Si l’objet de sens au modèle sous forme de chaîne, ce qui signifie que la valeur réelle sera une chaîne de caractères dactylographiés brute, sans ornement — mais peuvent uniquement être de quelques valeurs, vous pouvez ensuite utiliser un TypeScript « chaîne littéral type » dans TypeScript, comme suit :
export type Languages = "C#" | "Visual Basic" |
"F#" | "ECMAScript" | "TypeScript"
Pour l’essentiel, il s’agit d’une chaîne énumérée : instances de l’objet peuvent uniquement être remplies avec les valeurs spécifiées dans le « ou »-expression d’assignation, dans ce cas, une des cinq langues Microsoft de style. Ceci dit, toutefois, à compter de TypeScript 2.4, il est également possible d’écrire un type énuméré complet à l’aide de la chaîne de sauvegarde pour le stockage, comme suit :
export enum Subject {
CSHARP = 'C#', FSHARP = 'F#',
VB = 'Visual Basic', ES = 'ECMAScript',
TS = 'TypeScript'
}
Cela aura quelques avantages lorsque vous accédez à la modélisation les cases à cocher qui contiendra ces cinq valeurs pour la sélection ; l’inconvénient de l’aide du type énuméré, est bien sûr, qu’il ne peut pas contenir une autre qu’un des cinq valeurs possibles de sujet. (Langues est, au fond, une chaîne, et donc l’un de ses cinq valeurs peut être stocké sous forme de chaîne, qui peut être bien entendu dans une liste déroulante, ou vous pouvez avoir un champ d’édition de durée indéterminée permettent aux utilisateurs de taper dans d’autres valeurs au-delà de ces).
Supposons que l’enum est le choix par défaut pour le moment, et que le haut-parleur a un tableau d’instances d’objet, appelé « objets ». C’est tout à cela pour l’instant.
Modification ? Ou simplement afficher ?
Du point de vue de l’interface utilisateur, il est généralement préférentiel si le composant d’interface utilisateur peut savoir si l’instance en cours affiché est en cours de modification ou simplement examiné ; vous allez simplement souhaiter afficher les détails de l’intervenant, tandis qu’à d’autres moments, que vous souhaitez être en mesure de les modifier. L’interface utilisateur est souvent choisir d’afficher les détails différemment lorsqu’en cours de modification (à l’aide de contrôles de champ d’édition) que quand elles sont affichées (simplement laisser sous la forme de texte brut) afin d’indiquer clairement à l’utilisateur lorsqu’un problème est modifiable. Angulaire prend en charge, de manière légèrement détournée.
Pour commencer, vous devez le composant de savoir si elle est en lecture seule ou non ; le moyen le plus simple à un modèle qui doit avoir un champ booléen privé dans le composant de ce nom exact :
@Component({
selector: 'app-speaker-ui',
templateUrl: './speaker-ui.component.html',
styleUrls: ['./speaker-ui.component.css']
})
export class SpeakerUIComponent implements OnInit {
@Input() model: Speaker | number | undefined;
public readonly = true;
En lecture seule par défaut true consiste à goûts personnels ou contexte d’application.
Une fois que ce champ est établi, le modèle peut faire la différence entre les deux États et choisir entre une des deux sections différentes div dans le modèle en définissant l’attribut masqué div à true ou false en conséquence :
<form>
<div [hidden]="readonly">
...
</div>
<div [hidden]="!readonly">
...
</div>
</form>
Ici, la première section est masquée si la valeur de l’indicateur en lecture seule ; qui facilite la section modifiable affichée ; la deuxième section, est par conséquent, la section en lecture seule (c'est-à-dire, il n’est pas masqué si le composant n’est pas en lecture seule). Notez comment la syntaxe de liaison de propriété (les crochets) est utilisée pour lier au champ en lecture seule du composant, le cas échéant, à l’aide de la syntaxe d’expression angulaire inversion.
Affichage
La deuxième section en lecture seule est assez simple : La syntaxe de double-crochet angulaire permet simplement d’afficher les valeurs des champs du modèle et afficher un bouton Modifier pour lancer le composant en mode de modification lorsque l’utilisateur souhaite modifier l’instance de l’orateur :
<form>
<div [hidden]="readonly">
...
</div>
<div [hidden]="!readonly">
FirstName: {{model.firstName}}<br>
LastName: {{model.lastName}}<br>
Subjects: <span>{{model.subjects}}</span><br>
<button (click)="edit()">Edit</button>
</div>
</form>
La fonction Modifier sur le composant sera retourner le champ readonly à false, mais qui s’affiche est intéressant de fonctionnalités. Normalement, lorsqu’un type de modification est présenté à l’utilisateur, il existe également une opportunité pour annuler cette modification et revenez à l’état d’origine via un bouton Annuler. Si cette fonctionnalité est souhaitée ou nécessaire dans ce cas, vous devrez sans les valeurs d’origine pour la récupération ultérieure cache si l’utilisateur sélectionne l’annuler. Par conséquent, un nouveau champ, mis en cache (de type haut-parleur), doit être ajouté et les valeurs du modèle copiée sur :
edit() {
this.readonly = false;
this.cached = new Speaker();
this.cached.id = (<Speaker>this.model).id;
this.cached.firstName = (<Speaker>this.model).firstName;
this.cached.lastName = (<Speaker>this.model).lastName;
this.cached.votes = (<Speaker>this.model).votes;
this.cached.subjects = (<Speaker>this.model).subjects;
}
L’interface utilisateur s’affiche en mode de modification.
Modification
Modification, puis, utilise les champs d’entrée au lieu de la syntaxe encadrée en double, mais angulaire conserve une autre surprise : Vous pouvez utiliser la directive ngModel pour aider à angulaire certains comportements relatifs à la forme, telles qu’automatiquement double liaison du modèle (l’objet haut-parleur) pour les différents champs de formulaire et leur donnez certaines prédéfinies comportement lorsque les champs obtient modifiés.
La première étape consiste à dire angulaire qu’il s’agit d’un formulaire pour lequel la prise en charge du modèle est demandée ; Pour cela, vous devez créer une référence de variable de modèle pour l’objet de formulaire sur l’étiquette de formulaire dans le modèle :
<form #speakerForm="ngForm">
...
</form>
Cela indique à angulaire que vous souhaitez angulaire « effectuer son travail de l’écran. » À partir de là, vous pouvez utiliser l’attribut ngModel sur les différents champs d’entrée pour fournir la liaison de claire à partir du champ de modèle sans nécessiter aucun travail supplémentaire, comme indiqué dans Figure 1.
Figure 1 à l’aide de l’attribut ngModel
<form #speakerForm="ngForm">
<div [hidden]="readonly">
FirstName: <input name="firstName" type="text"
[(ngModel)]="model.firstName"><br>
LastName: <input name="lastName" type="text"
[(ngModel)]="model.lastName"><br>
Subjects: <span>{{model.subjects}}</span><br>
<button (click)="save()"
[disabled]="!speakerForm.form.valid">Save</button>
<button [disabled]="speakerForm.form.pristine"
(click)="cancel()">Cancel</button>
<br><span>{{diagnostic}}</span>
</div>
<div [hidden]="!readonly">
. . .
</div>
</form>
Il existe plusieurs choses intéressantes passe dans la Figure 1.
Tout d’abord, notez le « {{diagnostic}} en bas du formulaire. Il s’agit d’une astuce utile pour voir ce qui se passe dans le composant que vous êtes modification/affichage du composant. Pour ce faire, sur vos propres composants, définissez une méthode get de propriété appelée diagnostic qui exporte les éléments intéressants :
get diagnostic() {
return 'readonly:' + this.readonly + ';'
+ 'cached:' + JSON.stringify(this.cached) + ';'
+ 'model:' + JSON.stringify(this.model);
}
Cela est utile pour voir qu’angulaire change littéralement, et l’objet de modèle en mémoire en réponse à chaque séquence de touches qui apparaît dans les formulaires d’entrée. (Il est également utile pour s’assurer que le comportement de mise en cache, pour la prise en charge l’annulation, se comporte correctement, bien que réaliste cette valeur doit être l’objet de tests unitaires avant d’accepter comme étant authentique et exempt de bogue.)
En second lieu, notez comment les champs d’entrée firstName et lastName comportent un attribut en mode double liaison appelée ngModel, faisant référence à la propriété de l’objet de modèle à laquelle ces champs doivent être liés. La liaison en mode double (la syntaxe [(...)]) suggère que les modifications apportées à l’interface utilisateur ou le modèle sous-jacent seront automatiquement répercutées dans l’autre, ce qui laisse peu à faire par programme. Il est presque identique à la liaison bidirectionnelle à partir d’AngularJS, qui a toujours été un des avantages de cette infrastructure.
Enfin, notez comment le bouton Enregistrer est activé uniquement si speakerForm.form (l’objet de formulaire définie via la syntaxe # dans l’élément form) a une propriété valide qui a la valeur false. Valide est une de plusieurs propriétés de la forme expose pour indiquer si le formulaire nécessite une sauvegarde. Plusieurs autres propriétés sont présentes, y compris la propriété dénuée référencée dans le bouton d’annulation, mais cette discussion doit être différée jusqu'à ce que la colonne suivante, lors de la validation de formulaire parler.
L’enregistrement et méthodes d’annuler, puis, sont assez facile d’imaginer que :
save() {
this.cached = undefined;
this.readonly = true;
}
cancel() {
this.readonly = true;
// Bring back cached values
this.model = this.cached;
// Clear out cache
this.cached = undefined;
}
Là encore, tout ceci est simplement la manipulation de l’ordinateur d’état de deux États pour naviguer dans les deux sens entre modification et l’affichage en mode avec prise en charge de l’annuler.
Pour résumer
Avec une dip rapide du stylet (pour ainsi dire), j’ai ouvert pour être sûr d’un objet volumineux. Prise en charge d’angulaire pour l’entrée de formulaire est étendu, pour le moins, en particulier lorsqu’elles sont combinées avec certaines des méthodes de cycle de vie du composant, telles que ngOnInit, où une initialisation a généralement lieu pour établir le contenu initial de l’interface utilisateur. Dans la SpeakerUI, par exemple, ngOnInit ressemblera à la propriété d’entrée du modèle, et si elle n’est pas défini, supposons un nouvel utilisateur est créé ; Si c’est un nombre, supposons que l’ID de la SpeakerService doit être extrait ; et si elle est un objet haut-parleur, qui est l’objet pour l’utiliser comme modèle. Il est raisonnable de penser qu’autres méthodes de cycle de vie impossible jouent un rôle dans l’interaction du composant avec le système environnant, ainsi, en fonction des circonstances.
Dans la colonne suivante, je vais examiner les fonctionnalités de validation de formulaire d’angulaire, permettant à la fois un prénom et un nom doivent être obligatoire des haut-parleurs, entre autres choses. Que je vais également examiner comment les nouveaux sujets sur haut-parleurs peuvent être capturés et jeter dans le composant Upvote qui a été construit oh donc-long il y a. Entre-temps, toutefois... Amusez-vous !
Ted Newardest consultant de polytechnology de basée à Seattle, haut-parleur et un responsable, chargée en tant que le directeur des Relations de développeur à Smartsheet.com. Il a écrit une multitude d’articles, créés et livres une dizaine et parle partout dans le monde. Contacter à l’adresse ted@tedneward.com ou lire son blog à adresse blogs.tedneward.com.
Merci à l'expert technique suivant d'avoir relu cet article : Garvice Eakins