Vous êtes sur la page 1sur 9

EXAMEN : Module Application cote Client 1

Semestre : 1 2
Session : Principale Rattrapage

Module: Application côté client 1


Enseignant(s): UP web
Classes : 4TWIN
Documents autorisés : OUI NON Nombre de pages : 8
Calculatrice autorisée : OUI NON Internet autorisée : OUI NON
Date : 12/01/2022 Heure: 15h Durée :1h30

NB : Une feuille de réponses est fournie avec l’examen.

Exercice 1 : QCM (8 pts)

1- Parmi les propositions suivantes, lesquelles sont des technologies frontend ?


A) VueJS
B) ReactJS
C) Angular
D) Les réponses A, B et C sont correctes.

2- Dans quel fichier sont déclarées les dépendances d’une application Angular ?
A) angular.json
B) packages.json
C) tsconfig.json
D) tsLint.json

3- Lequel des répertoires suivants n’est pas un sous-répertoire de src ?


A) nodes_modules
B) app
C) assets
D) environements

4- C’est quoi la propriété « paramMap » de la classe ActivatedRoute ?


A) paramMap est un objet littéral des paramètres dans le chemin URL d'une route.
B) paramMap est un Observable qui retourne les valeurs des paramètres qui font partie du chemin
URL d'une route.
C) paramMap est un tableau indexé qui contient les paramètres dans le chemin URL d'une route.
D) paramMap est un observable qui retourne les segments d'URL correspondant à cette route.

5- A quoi sert la méthode RouterModule.forRoot ?


A) Enregistrer tous les fournisseurs que vous avez l'intention d'utiliser dans les composants
acheminés.
B) Enregistrer les définitions des routes au niveau de l'application racine.
C) Déclarer un service de routing dans le module racine.
D) Déclarer que vous avez l'intention d'utiliser le routage uniquement au niveau de la racine.

1
6- Comment utiliser le HttpClient pour envoyer une requête POST à un endpoint (Order.url) à
partir d'une fonction addOrder dans cet OrderService ?

A) return this.httpClient.url(order.url).post(order);
B) return this.httpClient.send(order.url, order);
C) return this.httpClient.post(order.url, order);
D) return this.httpClient.post(order.url, order).subscribe();
7- Quelle est la différence entre ces deux exemples de balises pour le traitement conditionnel de
l'affichage ?

A) Le ngIf est un raccourci pour l'autre exemple. Lorsque Angular traite cette directive, il écrit un
élément div dans le DOM avec la propriété hidden.
B) Ils sont fondamentalement les mêmes.
C) La directive ngIf ne rend pas le div dans le DOM si l'expression est fausse. L'utilisation de la
propriété hidden masque le contenu du div dans la fenêtre du navigateur, mais le div est toujours
dans le DOM.
D) La directive ngIf est valide, mais l'utilisation de la propriété hidden est incorrecte et entraînera
une erreur.
8- Comment désactiver le bouton d'envoi lorsque le formulaire comporte des erreurs dans cet
exemple de formulaire template-driven ?

A) <button (click)="submit(userForm.value)" disable="userForm.invalid">Save</button>


B) <button(click)="submit(userForm.value)"[disabled]="userForm.invalid">Save</button>
C) <button(click)="submit(userForm.value)" [ngForm.disabled]="userForm.valid">Save</button>
D) <button (click)="submit(userForm.value)" *ngIf="userForm.valid">Save</button>
9- Que sont les hooks du cycle de vie d'un composant Angular ?
A) Des méthodes permettant de suivre les étapes d’exécution d'une application Angular
B) Des fournisseurs qui peuvent être utilisés pour suivre les instances des composants.
C) Des tuyaux intégrés qui peuvent être utilisés dans les modèles pour les événements DOM
D) Des méthodes nommées réservées aux composants et aux directives qu'Angular appelle à des
moments précis de son exécution et qui peuvent être utilisées pour exploiter ces moments du cycle
de vie.

2
10- Quelle syntaxe de template-driven pouvez-vous utiliser sur ce champ de formulaire pour
accéder aux propriétés du champ et vérifier sa validité ?

A) Vous pouvez utiliser une variable référence de template exportant la directive ngModel et utilisez
cette variable par la suite pour accéder aux propriétés du champ.
B) Vous pouvez utiliser le name du champ d'entrée.
C) Vous pouvez utiliser une variable référence de template pour l'élément de saisie HTML, puis
vérifier la validité de la propriété à partir de cette variable.
D) Il n'est pas possible d'accéder aux propriétés du champ avec des formulaires template driven.
Vous devez utiliser des formulaires réactifs pour cela.

11- A quoi ressemblera le segment URL en fonction de l'appel suivant à la méthode


Router.navigate lorsque la valeur 15 est attribuée à goToUser ?

A) /user/15
B) /user?id=15
C) /user:15
D) /user;id=15

12- Que fait le décorateur Injectable sur cette classe de service ?

A) Il enregistre un fournisseur « provider » pour le service qui n'est disponible qu'au niveau du
module racine, et non pour les modules enfants.
B) Il enregistre un fournisseur « provider » pour le service dans l'injecteur de l'application racine,
rendant une seule instance de ce service disponible dans toute l'application.
C) Il fait en sorte que le service ne puisse être injecté que dans le composant d'amorçage
(bootstrapped) de l'application.
D) Il établit une règle de compilation qui vous permet de placer le type de service uniquement dans
la propriété des métadonnées des fournisseurs du NgModule racine.

13- Quelle est la directive utilisée pour lier une balise <a> au routage ?
A) routeTo
B) routerLink
C) routePath
D) appLink

3
14- Quelle est la syntaxe correcte pour utiliser la directive structurelle intégrée ngFor afin de
rendre une liste de noms de produits ?
A) <li [ngFor]="let productName of productNames">{{ productName }}</li>
B) <li ngFor="let productName of productNames">{{ productName }}</li>
C) <li *ngFor="let productName of productNames">{{ productName }}</li>
D) <? for productName in productNames { ?><li>{{ productName }}</li><? } ?>

15- Dans les formulaires réactifs, lequel des éléments suivants permet de créer un formulaire avec
un nombre d’éléments inconnu ?
A) FormArray
B) FormControl
C) FormGroup
D) Toutes les réponses

16- Quelle est la syntaxe correcte pour ajouter du style à un paragraphe « p » ?


A) <p [ngStyle]="{'font-style': 'italic'}">...</p>
B) <p [ngStyle.font-style]=" 'italic' ">...</p>
C) <p [ngStyle]="['font-style'=> 'italic']">...</p>
D) <p [ngStyle]="['font-style', 'italic']">...</p>

Exercice 2 : (1 pt)

Complétez les définitions suivantes

……. Data binding ……. est le moyen de partager les données entre une classe de composant et sa vue.

……. Les directives ……..sont des attributs qui permettent à l'utilisateur d'écrire une nouvelle syntaxe
HTML spécifique à ses applications

.@NgModule identifie les composants, les directives et les modules interne et externe d’un module.

ngOnChanges est une méthode hook appelée chaque fois qu'une ou plusieurs propriétés d'entrée du
composant changent.

Exercice 3 : (1.5 pts)

Donnez le code correspondant au traitement suivant :

Contenu de la page au chargement de Contenu de la page après le clic sur le


l’application (avant le clic sur le bouton) bouton.

app.component.ts app.component.html
export class AppComponent { <div>
show=true; {{message}}
message = "Bonjour tout le monde !" </div>
changeMsg(){ <button *ngIf="show"
this.show=false ; (click)="changeMsg()">Change</button>
this.message="Hello!"
}

4
}

Exercice 4 : (9.5 pt)

Soit une application Angular contenant, un module racine et un module nommé AppLibrary.

Soit un composant HomeComponent attaché au module racine.

Le module AppLibrary contient un composant LibraryComponent ayant comme selector « app-library »


et un composant BookComponent ayant comme selector « app-book ». Soit un modèle de donnée Book
définit comme suit :

export class Book{


id! : number;
title! : string;
author!:string;
}

Le composant BookComponent décrit les informations d’un « Book » dans sa vue.

Le composant LibraryComponent récupère la liste des « book » dans une propriété appelé listOfBooks
à partir de la méthode getAllBooks d’un service BookService.

Veuillez prendre en considération que la liste des livres est rendue par un REST Api sous format json
(http://localhost:3000/books).

Nous allons appliquer le lazy loading dans le chargement du module AppLibrary.

1- Quelle est la commande qui permet de créer le module AppLibrary avec son module de
routing associé et de l’attacher au module racine ? (0.25 pt)
…………………… ng g m AppLibrary --routing --module=app ………….………
2- Pour appliquer le Lazy Loading, le module AppLibrary doit il exister dans la liste des
imports du module racine ? Pourquoi ? (0.75 pt)
Non il ne doit pas exister. En effet, s’il existe il sera par défaut chargé au lancement de
l’application et on ne parle plus de lazy loading.

Au chargement de l’application, la page affichée contient deux liens : Home et Library. En cliquant sur
le lien « Home », le composant HomeComponent est chargé. En cliquant sur le lien « Libray » le
composant LibraryComponent est chargé en mode « lazy loaded ». Si l’utilisateur tape un path non
valide, un composant NotFoundComponent est chargé.

3- Complétez le code des fichiers suivants :


a. app.module.ts (1 pt)

@NgModule({
declarations: [
AppComponent,
…... HomeComponent…...,
…... NotFoundComponent…...
],
imports: [
…... BrowserModule …...,
AppRoutingModule,
HttpClientModule

5
],
providers: [],
bootstrap: [……AppComponent……..]
})
export class AppModule { }

b. app-routing.module.ts (1 pt)

const routes : Routes=[


{path:'home', component:HomeComponent},
{path :'library', loadChildren: () => import('./app-library/app-library.module').then(m
=> m.AppLibraryModule)
},
{path:'**', component:NotFoundComponent}
]

@NgModule({
imports: [RouterModule.forRoot(routes.)],
exports: [RouterModule]
})
export class AppRoutingModule { }

c. app.component.html (0.75 pt)

<a routerLink="/home"> Home </a>


<a routerLink="/library"> Library </a>
<router-outlet></router-outlet>

d. book.component.html (0.75 pt)

<fieldset>
<legend>Reference: {{book.id}}</legend>
<ul>
<li>Title : {{book.title}} </li>
<li>Author: {{book.author}} </li>
</ul>
</fieldset>

e. book.service.ts (1 pt)

@Injectable({
providedIn : 'root'
})
export class BookService {
bookUrl : string = "http://localhost:3000/books";

constructor(…private _http:HttpClient.) { }

6
getAllBooks() : Observable<Book[]>
return this._http.get< Book[]>(this.bookUrl);
}
}

f. libray.component.ts (0.5 pt)

export class LibraryComponent implements OnInit {


listOfBooks : Book[]=[];

constructor (private bs:BookService) { }

ngOnInit(): void {
this.bs.getAllBooks().subscribe (res=>this.listOfBooks=res)
}

4- Pour chaque « Book » dans listOfBooks, un composant BookComponent est créé et lui
sont envoyés les informations relatives au « Book » en question pour qu’il les affiche par
la suite dans sa vue. Ecrivez alors le contenu de la vue du composant LibraryComponent
Library.component.html (0.75 pt)

<div *ngFor="let b of listOfBooks">


<app-book [book]="b"></app-book>
</div>

Ou bien

<app-book *ngFor="let b of listOfBooks" [book]="b"></app-book>

5- Soit un champ de recherche au-dessous de la liste des « books » comme indiqué dans la
figure ci-dessous.

Si rien n’est saisie au niveau du champ alors tous les livres sont affichés. Si exactement le
« title » du « book » est écrit dans la zone de recherche, alors uniquement le livre
correspondant est affiché.

7
Ecrivez alors la condition nécessaire pour avoir le traitement décrit ci-dessus en tenant
compte de votre réponse dans la question précédente. (0.5 pt)

<div *ngFor="let b of listOfBooks">


<app-book *ngIf="title == '' || b.title == title" [book]="b"></app-book>
</div>

6- Nous allons créer maintenant un formulaire réactive pour ajouter un « book ». Complétez
le code nécessaire pour créer le formulaire dans la classe du composant
LibraryComponent. Vous êtes libre d’utiliser FormBuilder ou non. (1 pt)

this.formBook = new FormGroup({ (que se soit avec formBuilder ou non)


id : new FormControl('', Validators.required),
title : new FormControl('', Validators.required),
author : new FormControl('', Validators.required)
})

7- Complétez la partie HTML correspondante à ce formulaire. (1 pt)

<form [formGroup]="formBook">
<table>
<tr>
<td>id</td>
<td><input type="number" formControlName="id"></td>
</tr>
<tr>
<td>Title</td>
<td><input type="text" formControlName="title"></td>
</tr>
<tr>
<td>Author</td>
<td><input type="text" formControlName="author"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="addBook"></td>
</tr>
</table>
</form>

8
8- Comment résoudre l’erreur suivante ? (0.25 pt)

Can't bind to 'formGroup' since it isn't a known property of 'form'.

Importer ReactiveFormsModule dans app-library.module.ts dans la liste des imports

Vous aimerez peut-être aussi