Suivez votre progression
Accueil Trailhead
Accueil Trailhead

Attributs et expressions

Objectifs de formation

Une fois cette unité terminée, vous pourrez :
  • Définir des attributs de vos composants, et passer les valeurs d’attributs à des composants imbriqués.
  • Comprendre la différence entre une définition de composant et une instance de composant, et créer plusieurs instances d’un composant.
  • Créer des expressions basiques pour afficher des valeurs variables et calculées.
  • Créer des expressions conditionnelles pour une sortie dynamique.

Component Attributes

À ce stade, même si nous avons créé deux composants et que nous nous sommes bien familiarisés avec la création d’applications reposant dessus (à haut niveau), notre code n’en fait guère plus que du HTML simple. Quoi que nous fassions, nos deux composants affichent le même texte statique. Vous pourriez en mettre dix côte à côte et ils feraient tous la même chose.

Pas très folichon.

Pour y remédier, il nous faut apprendre deux choses. Tout d’abord, nous devons apprendre à permettre à un composant d’accepter une entrée lorsqu’il est créé. C’est-à-dire que nous devons pouvoir affecter des valeurs au composant. Pour ce faire, nous utiliserons des attributs.

(la deuxième chose que nous devons apprendre à faire, c’est à utiliser ces valeurs pour modifier le comportement et la sortie d’un composant. Nous le ferons une fois que nous aurons compris les attributs).

Les attributs des composants sont semblables à des variables d’instance dans des objets. Ils permettent d’enregistrer des valeurs modifiables, et de nommer les espaces réservés à ces valeurs. Par exemple, supposons que nous voulions développer un composant helloMessage affichant un message personnalisé. Nous pouvons imaginer ajouter un attribut Message à ce composant pour personnaliser sa sortie. Nous pourrons ensuite définir ce message en ajoutant le composant à notre application, comme ci-dessous.
<aura:component>
    <c:helloMessage message="You look nice today."/>
</aura:component>
Vous l'ajouterez à votre organisation, car nous allons l'utiliser plusieurs fois en progressant. Si vous le faites maintenant, vous obtiendrez une erreur. Pourquoi ? Le composant helloMessage n’existe pas encore. Salesforce valide votre code à mesure que vous le rédigez. Si vous essayez d’enregistrer un code non valide, par exemple en référençant un composant inexistant, vous obtenez une erreur. Par conséquent, commençons par créer le composant helloMessage.

Vous pouvez définir les attributs d’un composant lorsque vous le créez, comme nous l’avons fait dans l’exemple précédent. Vous pouvez aussi les modifier au cours du cycle de vie de votre composant, en réponse aux actions des utilisateurs ou à des événements se produisant ailleurs, etc. Bien entendu, il existe plusieurs façons de lire et d’utiliser les valeurs d’attribut. Nous les passerons en revue lorsque nous en viendrons aux expressions.

Pour l’instant, concentrons-nous sur la manière de définir les attributs d’un composant. Un attribut est défini en utilisant une balise <aura:attribute>, qui nécessite des valeurs pour les attributs name et type, et accepte les attributs facultatifs suivants : default, description et required.

Tout cela fait beaucoup d’emplois différents du terme « attribut » ! Trois concepts différents ont ici des noms similaires, il est donc très facile de les confondre. Soyons précis.

  1. Un attribut de composant est un endroit où vous pouvez stocker une valeur. Dans l’exemple précédent, le composant helloMessage est muni d’un attribut de composant nommé message. La plupart du temps, nous parlerons d’attributs de composant.
  2. Vous pouvez définir un attribut de composant à l’aide de la balise <aura:attribute>. Nous en verrons bientôt un exemple. Appelons ces éléments des « définitions d’attribut ».
  3. La balise <aura:attribute> hérite elle-même d’attributs lorsque vous l’utilisez ! En effet, lorsque vous définissez un attribut de composant avec la balise <aura:attribute>, vous affectez des attributs à <aura:attribute>, qui spécifient la « forme » de l’attribut de composant que vous définissez. Essayons de reformuler : on ajoute une définition d’attribut de composant en définissant les attributs de la définition d’attribut. La définition d’attribut de l’attribut de composant hérite-t-elle des attributs ?

Et voilà comment on fait pleurer un rédacteur technique. Essayons donc de résoudre ce problème de terminologie avec du code !

Voici le début de notre composant helloMessage :

<aura:component>
    <aura:attribute name="message" type="String"/>
    <p>Hello! [ message goes here, soon ]</p>
</aura:component>

Le composant helloMessage a un attribut de composant, et cet attribut est défini en réglant les valeurs name et type de l’attribut. Le nom de l’attribut est message et, une fois que nous nous serons familiarisés avec les expressions, c’est ainsi que vous y accéderez. La sortie est toujours du texte statique et du HTML, mais nous nous rapprochons de quelque chose d’utile.

?

Nous avons également utilisé un autre attribut, type. Nous l’avons défini, car il est requis dans une définition d’attribut. Il indique que le contenu de l’attribut message est une chaîne de caractères, ce qui est logique. Nous reparlerons des types de données d’attribut ainsi que des autres étapes des définitions d’attribut, mais commençons par apprendre à utiliser les expressions, de manière à ce que helloMessage fasse vraiment quelque chose.

Expressions

Au lieu de nous perdre à nouveau dans les mots, passons directement à faire fonctionner helloMessage comme prévu.

<aura:component>
    <aura:attribute name="message" type="String"/>
    <p>Hello! {!v.message}</p>
</aura:component>

Ce n’est peut-être pas ce que vous attendiez !

Nous affichons le contenu de message grâce à l’expression {!v.message}. Cela signifie que cette expression se réfère à l’attribut message. L’expression est évaluée et renvoie à la chaîne de caractères actuellement stockée dans message. Et c’est ce que l’expression affiche dans le corps du composant.

Mais... c’est quoi une « expression » ?

Une expression est une sorte de formule, ou de calcul, que vous placez entre des séparateurs d’expression (« {! » et « } »). Une expression ressemble donc à :

{!<expression>}

La définition formelle d’une expression est un peu intimidante, mais étudions-la quand même pour la décortiquer : Une expression correspond à tout ensemble de valeurs littérales, de variables, de sous-expressions ou d’opérateurs qui peut être résolu en une valeur unique.

Donc en fait, c’est une formule, presque comme celles que vous écririez dans un champ de calcul, un critère de filtrage ou Visualforce. La formule ou expression peut contenir différentes choses. Les valeurs littérales sont simples à comprendre. Il s’agit d’éléments comme le nombre 42, ou la chaîne de caractères « Bonjour ». Les variables sont des choses comme l’attribut message. Les opérateurs sont les signes tels que +, -, etc., et les sous-expressions permettent essentiellement de regrouper plusieurs éléments grâce à des parenthèses.

On va essayer tout ça en rendant notre expression un peu plus complexe.

<aura:component>
    <aura:attribute name="message" type="String"/>
    <p>{!'Hello! ' + v.message}</p>
</aura:component>

Tout ce que nous avons fait, c’est de prendre la partie « Bonjour », qui était un texte statique extérieur à l’expression, pour en faire un texte littéral à l’intérieur de l’expression. Remarquez que nous avons utilisé l’opérateur « + » pour concaténer les deux chaînes de caractères. Cela peut sembler être une infime différence, mais placer la formule de salutation dans l’expression vous permet d’utiliser des étiquettes au lieu de texte littéral, ce qui facilite la mise à jour (et la traduction) de vos composants. Par exemple :

{!$Label.c.Greeting + v.message}

Avez-vous remarqué ce que notre définition formelle des expressions ne couvrait pas ? Les appels à des fonctions JavaScript. Vous ne pouvez pas utiliser JavaScript dans les expressions du balisage des composants Aura.

Dernière chose à propos des expressions avant de changer de sujet. Vous pouvez les transmettre à un autre composant pour définir sa valeur. Voici un nouveau composant qui transmet une valeur personnalisée aux composants helloMessage. En transmettant la valeur à un autre composant, vous remplacez sa valeur.
<aura:component>
    <aura:attribute name="customMessage" type="String"/>
    <p> <c:helloMessage message="{!v.customMessage}"/> </p>
</aura:component>
.

Value Providers

Il y a un autre aspect des expressions dont nous devons parler. Dans les exemples précédents, nous avons appelé la référence à l’attribut message du composant helloMessage grâce à v.message. À quoi correspond donc ce « v. » ?

v est ce que l’on appelle un fournisseur de valeur. Les fournisseurs de valeur permettent de regrouper, d’encapsuler et d’accéder à des données liées. Les fournisseurs de valeur sont un sujet complexe, donc pour l’instant, contentez-vous de voir v comme une variable automatique à votre disposition. Dans notre composant, v est un fournisseur de valeur pour la vue, à savoir le composant helloMessage.

v vous donne un « hook » (hameçon) pour accéder à l’attribut message du composant, et c’est de cette manière que vous accéderez à tous les attributs d’un composant.

Les valeurs dans un fournisseur de valeur sont accessibles comme propriétés nommées. Pour utiliser une valeur, séparez le fournisseur de valeur et le nom de propriété par un point. Nous avons vu l’exemple de v.message.

Lorsqu’un attribut d’un composant est un objet ou un autre type de donnée structurée (pas une valeur primitive), accédez aux valeurs sur cet attribut à l’aide de la même notation pointée. Par exemple, {!v.account.id} accède au champ ID dans l’enregistrement d’un compte. Pour les attributs et objets imbriqués sur plusieurs niveaux, continuez d’ajouter des points pour traverser la structure et accéder aux valeurs imbriquées.

Types de données d’attribut

Le fait d’accéder à des données structurées est une bonne manière de revenir à la question des attributs, et de nous intéresser plus particulièrement aux types d’attributs non primitifs. Par exemple, message est une chaîne de caractères, mais il existe différents types d’attributs.

  • Les types de données primitifs, tels que Boolean, Date, DateTime, Decimal, Double, Integer, Long ou String. Les grands classiques des langages de programmation.
  • Les objets Salesforce standard et personnalisés, tels que Account ou MyCustomObject__c.
  • Les collections, telles que List, Map et Set.
  • Les classes Apex personnalisées.
  • Les types spécifiques à la structure, tels que Aura.Component ou Aura.Component[]. Ces types sont plus avancés que ceux abordés dans ce module, mais vous devez savoir qu’ils existent.

Voici un aperçu simplifié du composant expenseItem, que nous remplirons plus tard. Il montre comment définir un attribut pour un objet personnalisé et accéder aux champs d’un enregistrement.

<aura:component>
    <aura:attribute name="expense" type="Expense__c"/>
    <p>Amount:
        <lightning:formattedNumber value="{!v.expense.Amount__c}" style="currency"/>
    </p>
    <p>
        Client: {!v.expense.Client__c}
    </p>
    <p>
        <lightning:input type="toggle"
                         label="Reimbursed?"
                         name="reimbursed"
                         checked="{!v.expense.Reimbursed__c}" />
     </p>
    <!-- Other markup here -->
</aura:component>

Ce composant a un attribut, expense, qui est l’objet personnalisé que nous avons créé au tout début de ce module. L’objectif du composant est d’afficher les détails d’une dépense en référençant le champ de l’enregistrement Expense__c à l’aide de l’expression {!v.expense.fieldName}. Nous utilisons le composant <lightning:input> de type="toggle", qui est une case à cocher sous la forme d’un commutateur, pour pouvoir mettre à jour la valeur ultérieurement dans l’interface utilisateur.

Autres aspects des définitions d’attributs

Voici les autres choses à savoir concernant les attributs que vous affectez à la balise <aura:attribute>.

  • L’attribut default définit la valeur par défaut de l’attribut. Il est utilisé lorsque l’attribut est référencé et que vous n’avez pas encore défini sa valeur.
  • L’attribut required définit si l’attribut est obligatoire. Le paramètre par défaut est false.
  • L’attribut description contient un résumé concis de l’attribut et de la manière dont il est utilisé.

Définir la valeur par défaut peut être difficile pour un attribut dont le type de données est complexe. Nous verrons un exemple plus tard. Mais au moins, vous êtes prévenu.

Amusons-nous un peu avec les attributs et expressions

Pour illustrer quelques nouveaux concepts touchant aux attributs et expressions, nous allons créer un composant vraiment absurde, helloPlayground, qui contient le balisage suivant.

<aura:component>
    <aura:attribute name="messages" type="List"
        default="['You look nice today.',
            'Great weather we\'re having.',
            'How are you?']"/>
    <h1>Hello Playground</h1>
    <p>Silly fun with attributes and expressions.</p>
    <h2>List Items</h2>
    <p><c:helloMessage message="{!v.messages[0]}"/></p>
    <p><c:helloMessage message="{!v.messages[1]}"/></p>
    <p><c:helloMessage message="{!v.messages[2]}"/></p>
    <h2>List Iteration</h2>
    <aura:iteration items="{!v.messages}" var="msg">
        <p><c:helloMessage message="{!msg}"/></p>
    </aura:iteration>
    <h2>Conditional Expressions and Global Value Providers</h2>
    <aura:if isTrue="{!$Browser.isIPhone}">
        <p><c:helloMessage message="{!v.messages[0]}"/></p>
    <aura:set attribute="else">
        <p><c:helloMessage message="{!v.messages[1]}"/></p>
        </aura:set>
    </aura:if>
</aura:component>

Ajoutez maintenant le composant helloPlayground à votre application et observez le résultat !

Il y a plusieurs nouveautés. Nous n’allons pas toutes les approfondir tout de suite, mais vous les reverrez toutes.

D’abord, helloPlayground a un attribut, messages, qui est un type de données complexe, une liste. Et cette liste a une valeur par défaut, un tableau comprenant trois chaînes de caractères entre guillemets simples et séparées par des virgules. Et dans la section Éléments de la liste, vous pouvez voir comment accéder à chaque chaîne de caractères grâce à son index.

Que se passe-t-il si quelqu’un crée un <c:helloPlayground> avec seulement deux messages ? Tenter d’accéder au troisième message échouera, et bien que ce ne soit pas suffisant pour causer un plantage dans ce cas, ce pourrait être le cas avec des composants plus complexes.

Donc dans la section Itérer sur la liste, vous verrez une meilleure manière de parcourir tous les éléments de la liste. Le composant <aura:iteration> répète son corps une fois par élément présent dans son attribut items, donc la liste s’allonge ou se raccourcit en fonction du nombre de messages.

Dans la section Expressions conditionnelles et fournisseurs de valeurs globales, vous découvrirez une manière de choisir entre les deux sorties possibles. Le format est un peu complexe car il s’agit de balisage plutôt que de JavaScript, par exemple, mais le composant <aura:if> vous permet d’ajouter un bouton de modification à une page seulement si l’utilisateur dispose de droits d’édition sur l’objet.

Enfin, quelque chose d’un peu moins évident. En programmation orientée objet, il y a une différence entre une classe et une instance de cette classe. Les composants ont un concept similaire. Lorsque vous créez une ressource .cmp, vous fournissez la définition (classe) de ce composant. Lorsque vous insérez une balise de composant dans un .cmp, vous créez une référence vers (une instance de) ce composant.

Il n’est pas étonnant de pouvoir ajouter plusieurs instances du même composant avec différents attributs. Dans l’exemple précédent, si vous utilisez les valeurs par défaut pour les messages, vous vous retrouverez avec huit références à (ou instances de) notre composant <c:helloMessage>. Si vous lui passez une liste plus longue, vous en obtiendrez (beaucoup) plus. Tout ça à partir d’un petit composant !

Et maintenant, vous êtes fin prêt pour du vrai travail.