Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Notes
Cette page a été supprimée car AnuglarJS v1 est très ancien et n’est plus pris en charge par la maintenance Angular.
Si vous connaissez AngularJS, vous pouvez également utiliser cette infrastructure populaire pour créer des composants WebPart côté client. Grâce à sa modularité, elle peut aussi bien être utilisée pour des applications monopages complexes à plusieurs modes d’affichage que pour des composants plus petits, comme des composants WebPart. De nombreuses organisations utilisent AngularJS pour créer des solutions SharePoint depuis des années. Cet article explique comment utiliser AngularJS pour générer un composant WebPart côté client pour SharePoint Framework et lui attribuer un style à l’aide d’Office UI Fabric.
Dans ce didacticiel, vous générez un composant WebPart simple qui gère les tâches à effectuer.
La source du composant WebPart de travail est disponible sur GitHub à l’adresse samples/angular-todo/.
Notes
Avant de suivre la procédure décrite dans cet article, n’oubliez pas de configurer votre environnement de développement pour générer des solutions SharePoint Framework.
Création d’un projet
Créez un dossier pour votre projet :
md angular-todo
Accédez au dossier du projet :
cd angular-todo
Dans le dossier du projet, exécutez le générateur Yeoman pour SharePoint Framework afin de structurer un projet SharePoint Framework :
yo @microsoft/sharepoint
Lorsque vous y êtes invité, définissez les valeurs comme suit :
- angular-todo comme nom de votre solution
- Utiliser le dossier en cours pour l’emplacement des fichiers
- Aucune infrastructure JavaScript comme point de départ pour créer le composant WebPart
- Liste de tâches comme nom de votre composant WebPart
- Gestion simplifiée des tâches à effectuer comme description de votre composant WebPart
- Une fois la génération de modèles automatique terminée, verrouillez la version de dépendances du projet en exécutant la commande suivante :
npm shrinkwrap
Ouvrez le dossier de votre projet dans votre éditeur de code. Dans ce didacticiel, vous allez utiliser Visual Studio Code.
Ajout d’AngularJS
Dans ce didacticiel, vous chargez AngularJS à partir d’un CDN.
Dans l’éditeur de code, ouvrez le fichier config/config.json et, dans la propriété externals
, ajoutez les lignes suivantes :
"angular": {
"path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular.min.js",
"globalName": "angular"
}
Ajout des déclarations de type AngularJS pour TypeScript
Étant donné que vous référencez AngularJS dans le code de votre composant WebPart, vous avez également besoin des déclarations de type AngularJS pour TypeScript.
Pour les installer, exécutez le code suivant dans la ligne de commande :
npm install @types/angular --save-dev
Mise en œuvre d’une application AngularJS
Une fois toutes les conditions préalables remplies, vous pouvez commencer à implémenter l’exemple d’application AngularJS. Comme elle se compose de plusieurs fichiers, créez un dossier à part dédié, appelé app.
Implémentation du service de données pour les tâches à effectuer
Dans le dossier app nouvellement créé, créez un fichier appelé DataService.ts. Dans ce fichier, collez ce code :
export interface ITodo {
id: number;
title: string;
done: boolean;
}
export interface IDataService {
getTodos(hideFinishedTasks: boolean): angular.IPromise<ITodo[]>;
addTodo(todo: string): angular.IPromise<{}>;
deleteTodo(todo: ITodo): angular.IPromise<{}>;
setTodoStatus(todo: ITodo, done: boolean): angular.IPromise<{}>;
}
export default class DataService implements IDataService {
public static $inject: string[] = ['$q'];
private items: ITodo[] = [
{
id: 1,
title: 'Prepare demo Web Part',
done: true
},
{
id: 2,
title: 'Show demo',
done: false
},
{
id: 3,
title: 'Share code',
done: false
}
];
private nextId: number = 4;
constructor(private $q: angular.IQService) { }
public getTodos(hideFinishedTasks: boolean): angular.IPromise<ITodo[]> {
const deferred: angular.IDeferred<ITodo[]> = this.$q.defer();
const todos: ITodo[] = [];
for (let i: number = 0; i < this.items.length; i++) {
if (hideFinishedTasks && this.items[i].done) {
continue;
}
todos.push(this.items[i]);
}
deferred.resolve(todos);
return deferred.promise;
}
public addTodo(todo: string): angular.IPromise<{}> {
const deferred: angular.IDeferred<{}> = this.$q.defer();
this.items.push({
id: this.nextId++,
title: todo,
done: false
});
deferred.resolve();
return deferred.promise;
}
public deleteTodo(todo: ITodo): angular.IPromise<{}> {
const deferred: angular.IDeferred<{}> = this.$q.defer();
let pos: number = -1;
for (let i: number = 0; i < this.items.length; i++) {
if (this.items[i].id === todo.id) {
pos = i;
break;
}
}
if (pos > -1) {
this.items.splice(pos, 1);
deferred.resolve();
}
else {
deferred.reject();
}
return deferred.promise;
}
public setTodoStatus(todo: ITodo, done: boolean): angular.IPromise<{}> {
const deferred: angular.IDeferred<{}> = this.$q.defer();
for (let i: number = 0; i < this.items.length; i++) {
if (this.items[i].id === todo.id) {
this.items[i].done = done;
}
}
deferred.resolve();
return deferred.promise;
}
}
Dans l’extrait de code précédent, implémentez trois typages :
- L’interface ITodo, qui représente une tâche à effectuer dans votre application.
- L’interface IDataService, qui définit la signature du service de données.
- La classe DataService, qui récupère et manipule les tâches à effectuer.
Le service de données implémente des méthodes simples pour l’ajout et la modification des tâches à faire. Même si les opérations sont instantanées, chaque fonction CRUD renvoie une promesse, par souci de cohérence.
Dans ce didacticiel, les éléments « To Do » sont stockés en mémoire. Cependant, vous pouvez facilement étendre la solution pour stocker des éléments dans une liste SharePoint et utiliser le service de données pour communiquer avec SharePoint à l’aide de son API REST.
Mise en œuvre du contrôleur
Implémentez le contrôleur qui assure la communication entre l’affichage et le service de données.
Dans le dossier app, créez un fichier nommé HomeController.ts et collez-y le code suivant :
import { IDataService, ITodo } from './DataService';
export default class HomeController {
public isLoading: boolean = false;
public newItem: string = null;
public newToDoActive: boolean = false;
public todoCollection: any[] = [];
private hideFinishedTasks: boolean = false;
public static $inject: string[] = ['DataService', '$window', '$rootScope'];
constructor(private dataService: IDataService, private $window: angular.IWindowService, private $rootScope: angular.IRootScopeService) {
const vm: HomeController = this;
this.init();
}
private init(hideFinishedTasks?: boolean): void {
this.hideFinishedTasks = hideFinishedTasks;
this.loadTodos();
}
private loadTodos(): void {
const vm: HomeController = this;
this.isLoading = true;
this.dataService.getTodos(vm.hideFinishedTasks)
.then((todos: ITodo[]): void => {
vm.todoCollection = todos;
})
.finally((): void => {
vm.isLoading = false;
});
}
public todoKeyDown($event: any): void {
if ($event.keyCode === 13 && this.newItem.length > 0) {
$event.preventDefault();
this.todoCollection.unshift({ id: -1, title: this.newItem, done: false });
const vm: HomeController = this;
this.dataService.addTodo(this.newItem)
.then((): void => {
this.newItem = null;
this.dataService.getTodos(vm.hideFinishedTasks)
.then((todos: any[]): void => {
this.todoCollection = todos;
});
});
}
}
public deleteTodo(todo: ITodo): void {
if (this.$window.confirm('Are you sure you want to delete this todo item?')) {
let index: number = -1;
for (let i: number = 0; i < this.todoCollection.length; i++) {
if (this.todoCollection[i].id === todo.id) {
index = i;
break;
}
}
if (index > -1) {
this.todoCollection.splice(index, 1);
}
const vm: HomeController = this;
this.dataService.deleteTodo(todo)
.then((): void => {
this.dataService.getTodos(vm.hideFinishedTasks)
.then((todos: any[]): void => {
this.todoCollection = todos;
});
});
}
}
public completeTodo(todo: ITodo): void {
todo.done = true;
const vm: HomeController = this;
this.dataService.setTodoStatus(todo, true)
.then((): void => {
this.dataService.getTodos(vm.hideFinishedTasks)
.then((todos: any[]): void => {
this.todoCollection = todos;
});
});
}
public undoTodo(todo: ITodo): void {
todo.done = false;
const vm: HomeController = this;
this.dataService.setTodoStatus(todo, false)
.then((): void => {
this.dataService.getTodos(vm.hideFinishedTasks)
.then((todos: any[]): void => {
this.todoCollection = todos;
});
});
}
}
Commencez par charger le service de données précédemment mis en œuvre. Le contrôleur en a besoin pour obtenir la liste des éléments et les modifier selon les demandes de l’utilisateur. À l’aide de la fonctionnalité d’injection de dépendances d’AnguillaJS, le service est injecté dans le contrôleur. Ce dernier implémente un certain nombre de fonctions qui sont accessibles par le modèle d’affichage et seront appelées à partir du modèle. À l’aide de ces fonctions, les utilisateurs peuvent ajouter de nouveaux éléments, marquer des éléments comme terminés, ou tâches à faire ou, supprimer des éléments.
Mise en œuvre du module principal
Lorsque le service de données et le contrôleur sont prêts, définissez le module principal de votre application, et enregistrez le service de données et le contrôleur avec lui.
Dans le dossier app, créez un fichier appelé app-module.ts et collez-y le contenu suivant :
import * as angular from 'angular';
import HomeController from './HomeController';
import DataService from './DataService';
const todoapp: angular.IModule = angular.module('todoapp', []);
todoapp
.controller('HomeController', HomeController)
.service('DataService', DataService);
Commencez par référencer AngularJS et à charger le contrôleur et le service de données précédemment mis en œuvre. Ensuite, vous définissez le module pour votre application. Enfin, enregistrez le contrôleur et le service de données avec votre application.
Vous avez créé une application AngularJS pour votre composant WebPart. Dans la suite de la procédure, vous allez inscrire l’application AngularJS avec le composant WebPart et la rendre configurable à l’aide de propriétés de composant WebPart.
Inscription de l’application AngularJS avec un composant WebPart
L’objectif de cette étape est d’ajouter une application AngularJS au composant WebPart.
Dans l’éditeur de code, ouvrez le fichier ToDoWebPart.ts.
Juste avant la déclaration de classe, ajoutez les lignes suivantes :
import * as angular from 'angular'; import './app/app-module';
Ceci nous permet de charger une référence à AngularJS et à votre application, éléments tous deux nécessaires pour démarrer votre application AngularJS.
Définissez la fonction rendu() du composant WebPart sur :
public render(): void { if (this.renderedOnce === false) { this.domElement.innerHTML = ` <div class="${styles.toDo}"> <div data-ng-controller="HomeController as vm"> <div class="${styles.loading}" ng-show="vm.isLoading"> <div class="${styles.spinner}"> <div class="${styles.spinnerCircle} ${styles.spinnerLarge}"></div> <div class="${styles.spinnerLabel}">Loading...</div> </div> </div> <div ng-show="vm.isLoading === false"> <div class="${styles.textField} ${styles.underlined}" ng-class="{'${styles.isActive}': vm.newToDoActive}"> <label for="newToDo" class="${styles.label}">New to do:</label> <input type="text" label="New to do:" id="newToDo" value="" class="${styles.field}" aria-invalid="false" ng-model="vm.newItem" ng-keydown="vm.todoKeyDown($event)" ng-focus="vm.newToDoActive = true" ng-blur="vm.newToDoActive = false"> </div> </div> <div class="list" ng-show="vm.isLoading === false"> <div class="listSurface"> <div class="listPage"> <div class="listCell" ng-repeat="todo in vm.todoCollection" uif-item="todo" ng-class="{'${styles.done}': todo.done}"> <div class="${styles.listItem}"> <span class="${styles.listItemPrimaryText}">{{todo.title}}</span> <div class="${styles.listItemActions}"> <div class="${styles.listItemAction}" ng-click="vm.completeTodo(todo)" ng-show="todo.done === false"> <i class="${styles.icon} ${styles.iconCheckMark}"></i> </div> <div class="${styles.listItemAction}" ng-click="vm.undoTodo(todo)" ng-show="todo.done"> <i class="${styles.icon} ${styles.iconUndo}"></i> </div> <div class="${styles.listItemAction}" ng-click="vm.deleteTodo(todo)"> <i class="${styles.icon} ${styles.iconRecycleBin}"></i> </div> </div> </div> </div> </div> </div> </div> </div> </div>`; angular.bootstrap(this.domElement, ['todoapp']); } }
Le code assigne tout d’abord le modèle de votre application directement à l’élément DOM du composant WebPart. Sur l’élément racine, spécifiez le nom du contrôleur qui gère les événements et la liaison de données dans le modèle.
Amorcez votre application à l’aide du nom todoapp utilisé pour déclarer le module principal.
À l’aide de la propriété de composant WebPart
renderedOnce
, vérifiez que votre application AngularJS n’est amorcée qu’une seule fois. Sans cela, si vous avez modifié l’une des propriétés du composant WebPart, la fonctionrender()
est appelée à nouveau, ce qui amorce une nouvelle fois l’application AngularJS et entraîne une erreur.Implémentez les styles CSS utilisés dans le modèle. Dans l’éditeur de code, ouvrez le fichier ToDo.module.scss et remplacez son contenu par :
.toDo { .loading { margin: 0 auto; width: 6em; .spinner { display: inline-block; margin: 10px 0; @-webkit-keyframes spinnerSpin { 0% { -webkit-transform:rotate(0); transform:rotate(0); } 100% { -webkit-transform:rotate(360deg); transform:rotate(360deg); } } @keyframes spinnerSpin { 0% { -webkit-transform:rotate(0); transform:rotate(0); } 100% { -webkit-transform:rotate(360deg); transform:rotate(360deg); } } .spinnerCircle { margin: auto; box-sizing: border-box; border-radius: 50%; width: 100%; height: 100%; border: 1.5px solid #c7e0f4; border-top-color: #0078d7; -webkit-animation: spinnerSpin 1.3s infinite cubic-bezier(.53, .21, .29, .67); animation: spinnerSpin 1.3s infinite cubic-bezier(.53, .21, .29, .67); &.spinnerLarge { width: 28px; height: 28px; } } .spinnerLabel { color: #0078d7; margin-top: 10px; text-align: center; } } } .label { font-family: "Segoe UI WestEuropean", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; font-weight: 400; box-sizing: border-box; margin: 0; padding: 0; box-shadow: none; color: #333333; box-sizing: border-box; display: block; padding: 5px 0 } .textField { font-family: "Segoe UI WestEuropean", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; -webkit-font-smoothing: antialiased; box-sizing: border-box; margin: 0; padding: 0; box-shadow: none; color: #333333; font-size: 14px; font-weight: 400; margin-bottom: 8px; &.underlined { border-bottom: 1px solid #c8c8c8; display: table; width: 100%; &:hover { border-color: #767676; } &.isActive, &:active { border-color: #0078d7; } .field { border: 0; display: table-cell; padding-top: 8px; padding-bottom: 3px } } .label { padding-right: 0; padding-left: 12px; margin-right: 8px; font-size: 14px; display: table-cell; vertical-align: top; padding-top: 9px; height: 32px; width: 1%; white-space: nowrap; font-weight: 400; } .field { text-align: left; float: left; box-sizing: border-box; margin: 0; padding: 0; box-shadow: none; font-family: "Segoe UI WestEuropean", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; -webkit-font-smoothing: antialiased; border: 1px solid #c8c8c8; border-radius: 0; font-weight: 400; font-size: 14px; color: #333333; height: 32px; padding: 0 12px 0 12px; width: 100%; outline: 0; text-overflow: ellipsis; } .field:hover { border-color: #767676; } } .listItem { font-family: "Segoe UI WestEuropean", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; font-weight: 400; box-sizing: border-box; margin: 0; padding: 0; box-shadow: none; padding: 9px 28px 3px; position: relative; display: block; &::before { display: table; content: ""; line-height: 0; } &::after { display: table; content: ""; line-height: 0; clear: both; } .listItemPrimaryText { font-family: "Segoe UI WestEuropean", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; -webkit-font-smoothing: antialiased; font-size: 21px; font-weight: 100; padding-right: 80px; position: relative; top: -4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; } .listItemActions { max-width: 80px; position: absolute; right: 30px; text-align: right; top: 10px; .listItemAction { color: #a6a6a6; display: inline-block; font-size: 15px; position: relative; text-align: center; top: 3px; cursor: pointer; height: 16px; width: 16px; &:hover { color: #666666; outline: 1px solid transparent; } .icon { vertical-align: top; } } } } .done { text-decoration: line-through; } .icon { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; display: inline-block; font-family: FabricMDL2Icons; font-style: normal; font-weight: 400; speak: none; &.iconCheckMark::before { content: "\E73E"; } &.iconUndo::before { content: "\E7A7"; } &.iconRecycleBin::before { content: "\EF87"; } } }
Exécutez la commande suivante pour vérifier que tout fonctionne comme prévu :
gulp serve
Dans le navigateur, votre composant WebPart Liste de tâches affiche les tâches à réaliser.
Rendre le composant WebPart configurable
À ce stade, le composant WebPart To Do affiche une liste fixe To Do. Vous allez maintenant l’étendre avec une option de configuration permettant aux utilisateurs de choisir s’ils souhaitent voir les tâches marquées comme déjà faites.
Ajout de propriétés dans le manifeste du composant WebPart
Commencez par ajouter une propriété de configuration dans le manifeste du composant WebPart.
Dans l’éditeur de code, ouvrez le fichier ToDoWebPart.manifest.json. Dans la section preconfiguredEntries
, naviguez jusqu’au tableau properties
et remplacez la propriété description
existante par la ligne suivante :
"hideFinishedTasks": false
Mise à jour de la signature de l’interface des propriétés du composant WebPart
À présent, mettez à jour la signature de l’interface des propriétés du composant WebPart.
Dans l’éditeur de code, ouvrez le fichier ToDoWebPart.ts et mettez à jour l’interface IToDoWebPartProps
avec :
export interface IToDoWebPartProps {
hideFinishedTasks: boolean;
}
Ajout de la propriété au volet de propriétés du composant WebPart
Pour permettre aux utilisateurs de configurer la valeur de la propriété que vous venez d’ajouter, vous devez l’exposer par le biais du volet des propriétés du composant WebPart.
Dans l’éditeur de code, ouvrez le fichier ToDoWebPart.ts.
Dans la première instruction
import
, remplacezPropertyPaneTextField
parPropertyPaneToggle
:import { BaseClientSideWebPart, IPropertyPaneConfiguration, PropertyPaneToggle } from '@microsoft/sp-webpart-base';
Remplacez l’implémentation de la fonction
propertyPaneSettings
par :protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { return { pages: [ { header: { description: strings.PropertyPaneDescription }, groups: [ { groupName: strings.ViewGroupName, groupFields: [ PropertyPaneToggle('hideFinishedTasks', { label: strings.HideFinishedTasksFieldLabel }) ] } ] } ] }; }
Pour corriger les références de chaîne manquantes, vous devez d’abord modifier la signature de vos chaînes. Dans l’éditeur de code, ouvrez le fichier loc/mystrings.d.ts et remplacez son contenu par :
declare interface IToDoWebPartStrings { PropertyPaneDescription: string; ViewGroupName: string; HideFinishedTasksFieldLabel: string; } declare module 'ToDoWebPartStrings' { const strings: IToDoWebPartStrings; export = strings; }
Renseignez les valeurs réelles pour les chaînes nouvellement définies. Dans l’éditeur de code, ouvrez le fichier loc/en-us.js et remplacez son contenu par :
define([], function() { return { "PropertyPaneDescription": "Manage configuration of the To do web part", "ViewGroupName": "View", "HideFinishedTasksFieldLabel": "Hide finished tasks" } });
Exécutez la commande suivante pour vérifier que tout fonctionne comme prévu :
gulp serve
Dans le volet de propriétés du composant WebPart, un bouton bascule apparaît pour la propriété nouvellement définie.
À ce stade, le fait de cliquer sur le bouton bascule n’a aucun effet sur votre composant WebPart, car il n’a pas été connecté à AngularJS. C’est ce que vous allez faire à l’étape suivante.
Rendre l’application AngularJS configurable à l’aide des propriétés du composant WebPart
À l’étape précédente, vous avez défini une propriété de composant WebPart qui permet aux utilisateurs de choisir d’afficher les tâches terminées ou non. Vous allez maintenant transmettre la valeur sélectionnée par l’utilisateur dans l’application AngularJS pour qu’elle puisse charger les éléments en conséquence.
Diffusion d’un événement AngularJS après la modification d’une propriété de composant WebPart
Dans l’éditeur de code, ouvrez le fichier ToDoWebPart.ts. Juste au-dessus de la méthode
render()
, ajoutez la ligne suivante :private $injector: angular.auto.IInjectorService;
Définissez la fonction
render()
du composant WebPart sur la valeur suivante :public render(): void { if (this.renderedOnce === false) { this.domElement.innerHTML = ` <div class="${styles.toDo}"> <div data-ng-controller="HomeController as vm"> <div class="${styles.loading}" ng-show="vm.isLoading"> <div class="${styles.spinner}"> <div class="${styles.spinnerCircle} ${styles.spinnerLarge}"></div> <div class="${styles.spinnerLabel}">Loading...</div> </div> </div> <div ng-show="vm.isLoading === false"> <div class="${styles.textField} ${styles.underlined}" ng-class="{'${styles.isActive}': vm.newToDoActive}"> <label for="newToDo" class="${styles.label}">New to do:</label> <input type="text" label="New to do:" id="newToDo" value="" class="${styles.field}" aria-invalid="false" ng-model="vm.newItem" ng-keydown="vm.todoKeyDown($event)" ng-focus="vm.newToDoActive = true" ng-blur="vm.newToDoActive = false"> </div> </div> <div class="list" ng-show="vm.isLoading === false"> <div class="listSurface"> <div class="listPage"> <div class="listCell" ng-repeat="todo in vm.todoCollection" uif-item="todo" ng-class="{'${styles.done}': todo.done}"> <div class="${styles.listItem}"> <span class="${styles.listItemPrimaryText}">{{todo.title}}</span> <div class="${styles.listItemActions}"> <div class="${styles.listItemAction}" ng-click="vm.completeTodo(todo)" ng-show="todo.done === false"> <i class="${styles.icon} ${styles.iconCheckMark}"></i> </div> <div class="${styles.listItemAction}" ng-click="vm.undoTodo(todo)" ng-show="todo.done"> <i class="${styles.icon} ${styles.iconUndo}"></i> </div> <div class="${styles.listItemAction}" ng-click="vm.deleteTodo(todo)"> <i class="${styles.icon} ${styles.iconRecycleBin}"></i> </div> </div> </div> </div> </div> </div> </div> </div> </div>`; this.$injector = angular.bootstrap(this.domElement, ['todoapp']); } this.$injector.get('$rootScope').$broadcast('configurationChanged', { hideFinishedTasks: this.properties.hideFinishedTasks }); }
Dans l’exemple de code précédent, chaque fois que la propriété du composant WebPart est modifiée, le système diffuse un événement AngularJS auquel l’application AngularJS abonne le composant. L’application AngularJS traite l’événement dès qu’elle le reçoit.
S’abonner à un événement de modification de propriété de composant WebPart dans AngularJS
Dans l’éditeur de code, ouvrez le fichier app/HomeController.ts. Étendez le constructeur comme suit :
constructor(private dataService: IDataService, private $window: angular.IWindowService, private $rootScope: angular.IRootScopeService) { const vm: HomeController = this; this.init(); $rootScope.$on('configurationChanged', (event: angular.IAngularEvent, args: { hideFinishedTasks: boolean }): void => { vm.init(args.hideFinishedTasks); }); }
Pour vérifier que l’application AngularJS fonctionne normalement et répond correctement à la modification de propriété, exécutez ce qui suit dans la ligne de commande :
gulp serve
Si vous basculez la valeur de la propriété Masquer les tâches terminées, le composant WebPart affiche ou masque les tâches terminées comme demandé.