Tandis que je regarde un peu ce que propose VueJs, je vais mettre ici mes notes :
Pb de set-up avec VueJS:
- Nécessite une connexion avec GitHub pour récupérer le format de templating :/
- Notion de templating à approfondir ??? On ne sait pas trop quel template propose quoi...
Contournement sur Windows (sigh) :
- Récuperer le template sur Github (téléchargement direct)
- Le mettre dans un dossier C:/Users/****/.vue-template/NOMDUTEMPLATE
- Relancer la création de l'application : vue init NOMDUTEMPLATE NOMDUPROJET --offline
- Entrer dans le dossier contenant l'application
- npm install
- npm run dev
Du côté du build, on a deux commandes disponibles :
- dev : pour tester en live
- build : pour builder le tintouin.
Ca a l'avantage d'être déjà configuré. Le reload est rapide. Je pouce en l'air !
<a href="?addtag=Gestion" title="Hashtag Gestion">#Gestion</a> des composants :
Coupler les trois couches : js - css - html
Ou les séparer et les importer au besoin :
<template>
<div>This will be pre-compiled</div>
</template>
<script src="./my-component.js"></script>
<style src="./my-component.css"></style>
C'est bien de laisser le choix. La gestion des composants est très proche d'Aurélia : on peut importer n'importe quel composant dans n'importe quel autre sauf que l'import a lieu coté model, là ou Aurélia le met par défaut côté template (pas d'avis sur le sujet pour le moment).
Ça créé des problèmes si la personne n'est pas très propre sur son code (on ne sait pas quel composant est appelé où). Mais c'est plus un pb côté éditeur.
Je ne suis pas fan du côté module d'Angular : a voir si cette façon de faire est encore présente dans Angular 6 (Je connais très bien Angular 4 mais pas encore bien le 6 ni le 7)
Pré-requis : Component template should contain exactly one root element : un seul div racine <= pourquoi pas ! C'est pas plus mal :)
Le binding de class css est un peu foireux (plus proche de la logique angular) :
VueJS :
v-bind:class="{ active: isActive, 'text-danger': hasError }"
Aurelia :
class="${isActive ? 'active' : ''}"
Angular :
[class.active]="isActive"
Le binding de style est tout aussi dégueulasse :
VueJs :
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
Aurelia :
<div style="width: ${width}px; height: ${height}px;"></div>
Angular :
[style.color]="isSpecial ? 'red' : 'green'"
Conditional rendering : Pareil que la concurrence
VueJS :
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
Aurelia :
<div if.bind="greet">
Hello, World!
</div>
Angular :
<div *ngIf="show">
Text to show
</div>
C'est la même merde que les autres. Tout va bien :)
CELA DIT : SI TU FOIRES TA GESTION DU IF, T'AS QUAND MÊME GRAVE L'AIR D'UN CON !
V-if et v-for marchent pas ensemble. Comme partout ailleurs. RAS.
Et ils ont tellement merdé la conditionnelle de class et style qu'ils proposent v-show, qui ressemblerait globalement à
<div style="display:${mustbeshown}"></div>
chez Aurelia
Boucle dans le template : RAS
VueJS :
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
Aurelia :
<template>
<template repeat.for="friend of friends">
<p>Hello, ${friend}!</p>
</template>
</template>
Angular :
<li *ngFor="let user of userObservable">
{{user}}
</li>
Pas de choses fofolles côté event management ou forms.
Côté binding, on retrouve les bonnes idées Aurelia :
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title"
></blog-post>
Aurelia :
<blog-post
repeat.for="post in posts"
key.bind="post.id"
title.bind="post.title"
></blog-post>
Quand on aborde la question des events, là, je grince un peu des dents...
Appeler une méthode du model depuis la vue (via un boutton par exemple) :
VUEJS :
<template>
<div>
<button v-on:click="clickTest()">trololo pouet pouet click me</button>
</div>
</template>
<script>
module.exports= {
data: function () {
return {
clickTest: function () {
console.log("THIS SIS DGKMGHKGLKLK");
}
}
},
//OU :
methods: {
clickTest: function () {
console.log("THIS SIS DGKMGHKGLKLK");
toto="texte4"
}
}
}
</script>
AURELIA :
<template>
<button click.trigger="clickTest()">Cancel</button>
</template>
export class MYCOMPONENT {
public void clickTest() {
console.log("THIS SIS DGKMGHKGLKLK");
}
}
Angular :
<template>
<button (click)="clickTest()">Cancel</button>
</template>
export class MYCOMPONENT {
public void clickTest() {
console.log("THIS SIS DGKMGHKGLKLK");
}
}
On peut considérer la fonction comme étant une data... OK. Ou alors,y a un petit espace privatif pour les méthodes....
Cétait pas possible de définir un endroit pour tout mettre ? Il faut mettre les pommes dans le tiroir à pommes et les couteaux dans le bac à couteaux...
OUI MAIS ! pourquoi ? On distingue de manière physique les constantes, les variables bindées et les méthodes... on ne sait pas le faire sans distinguer ? Je ne veux pas être tributaire de votre synthaxe alambiquée, je veux pouvoir choisir d'encapsuler mes objets, de faire contenir mes méthodes dans des classes extérieures... et votre framework n'encourage pas du tout à penser le code de manière testable et autonome sans le framework...
Je ne comprend pas l'expérience utilisateur que vous avez pensée....
Le summum du cocobongo : Le data binding entre composants
Alors là, les gars de vueJs nous l'ont bien géré à l'antipattern angular :
To update the parent property, what you should do is $emit the updated value and listen for the change in the parent.
Vue.component("navigation-form",{
template: '#navigation-form',
props: ['propRoomSelected'],
data: function () {
return {
roomSelected: this.propRoomSelected,
}
},
methods:{
updateCoachStatus: function(event){
this.$emit("update-room-selected", 67) ;
}
}
})
Nan les gars, là je vous suis pas... Pourquoi ne pas faire comme Aurelia :
<component toto.bind="tata"></component>
export class Toto {
public toto: String;
public void changeToto() {
this.toto = "titi";
}
}
LE DOUBLE DATA BINDING DOIT ÊTRE NATIF ! PAS REIMPLEMENTE A CHAQUE VARIABLE AVEC DES RE-EMISSIONS A GOGO !
C'est chiant et lourd à lire, sans déconner...
CONCLUSION
Mon avis pour le moment :
1) La synthaxe VueJS est quand même très invasive côté "corporate".
ON SAIT QUE C'EST VUEJS !!! TOUS LES FICHIERS S'APPELLENT VUE BON SANG ! POURQUOI VOUS NOUS METTEZ DES PETITS V PARTOUT, BON SANG DE BOIS !
Note à postériori : Bon, ok, plutôt que v-bind:toto, on peut écrire :toto (OUF !)
2) Une vision très orienté JS
3) Un usage qui n'est pas très instinctif pour un dev
Un dev, pour déclencher l'usage d'une class de style, va naturellement penser conditionnelle et
class="{{isOK ? 'class1': 'class2'}}"
me semble plus instinctif à écrire que
v-bind:class="{ class1: isOK, class2: !isOk}"
4) La gestion du double data binding, ça m'a tuer (sans faute de frappe). C'est super moche.
Aurélia, tu as toujours la première place dans mon coeur <3 (udabest)
Le routage sous Angular4 se fait avec des liens complets plutôt qu'avec des ancres (fonctionnement Aurelia), ce qui pose des problèmes avec les serveurs comme SpringBoot (redirection compliquée). Toutefois, il est possible de forcer l'usage des ancres sous Angular4 :
fichier app.module.ts
import { RouterModule, Routes } from '@angular/router';
import { HashLocationStrategy, LocationStrategy } from '@angular/common';
import { AppComponent } from './app.component';
import { ComponentOne } from './one/one.component';
const appRoutes: Routes = [
{ path: 'home', component: Home },
{ path: 'login', component: Login },
{ path: 'one', component: ComponentOne},
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', redirectTo: '/home' }
];
@NgModule({
declarations: [
Home, Login, ComponentOne
],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
RouterModule.forRoot(appRoutes) <----- L'ajout de la configuration de routing au module
],
providers: [ { provide: LocationStrategy, useClass: HashLocationStrategy } ], <----- Impose l'usage des ancres pour la navigation
bootstrap: [ AppComponent ]
})
export class AppModule { }