-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathbackbone.en.douceur.html
6188 lines (5562 loc) · 554 KB
/
backbone.en.douceur.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<title></title>
<style type="text/css">
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; }
code > span.dt { color: #902000; }
code > span.dv { color: #40a070; }
code > span.bn { color: #40a070; }
code > span.fl { color: #40a070; }
code > span.ch { color: #4070a0; }
code > span.st { color: #4070a0; }
code > span.co { color: #60a0b0; font-style: italic; }
code > span.ot { color: #007020; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #06287e; }
code > span.er { color: #ff0000; font-weight: bold; }
</style>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div id="TOC">
<ul>
<li><a href="#préambule-remerciements"><span class="toc-section-number">1</span> Préambule & Remerciements</a><ul>
<li><a href="#avertissement"><span class="toc-section-number">1.1</span> Avertissement</a></li>
</ul></li>
<li><a href="#présentation-de-backbone-rappels-mvc"><span class="toc-section-number">2</span> Présentation de Backbone & rappels MVC</a><ul>
<li><a href="#backbone-webapps-mvc"><span class="toc-section-number">2.1</span> Backbone ? Webapps ? MVC ?</a><ul>
<li><a href="#quest-ce-quune-webapp"><span class="toc-section-number">2.1.1</span> Qu’est-ce qu’une “Webapp” ?</a></li>
<li><a href="#petit-rappel-mvc"><span class="toc-section-number">2.1.2</span> Petit rappel : MVC ?</a></li>
</ul></li>
<li><a href="#backbone-mvc"><span class="toc-section-number">2.2</span> Backbone & MVC</a></li>
<li><a href="#pourquoi-jai-choisi-backbone"><span class="toc-section-number">2.3</span> Pourquoi j’ai choisi Backbone ?</a></li>
</ul></li>
<li><a href="#tout-de-suite-les-mains-dans-le-cambouis"><span class="toc-section-number">3</span> Tout de suite “les mains dans le cambouis”</a><ul>
<li><a href="#prérequis-les-dépendances-de-backbone"><span class="toc-section-number">3.1</span> Prérequis : les dépendances de Backbone</a></li>
<li><a href="#outils-de-développement"><span class="toc-section-number">3.2</span> Outils de développement</a><ul>
<li><a href="#ide-editeur"><span class="toc-section-number">3.2.1</span> IDE (Editeur)</a></li>
<li><a href="#navigateur"><span class="toc-section-number">3.2.2</span> Navigateur</a></li>
</ul></li>
<li><a href="#initialisation-de-notre-projet-de-travail"><span class="toc-section-number">3.3</span> Initialisation de notre projet de travail</a><ul>
<li><a href="#installation"><span class="toc-section-number">3.3.1</span> Installation</a></li>
<li><a href="#préparons-notre-page-html"><span class="toc-section-number">3.3.2</span> Préparons notre page HTML</a></li>
</ul></li>
<li><a href="#jouons-avec-jquery"><span class="toc-section-number">3.4</span> Jouons avec jQuery</a><ul>
<li><a href="#jouons-avec-notre-page-en-mode-commande"><span class="toc-section-number">3.4.1</span> "Jouons" avec notre page en mode commande</a><ul>
<li><a href="#saisissons-nos-1ères-commandes"><span class="toc-section-number">3.4.1.1</span> Saisissons nos 1ères commandes :</a></li>
<li><a href="#modifions-laspect-de-notre-page-dynamiquement"><span class="toc-section-number">3.4.1.2</span> Modifions l’aspect de notre page dynamiquement :</a></li>
<li><a href="#allons-plus-loin"><span class="toc-section-number">3.4.1.3</span> Allons plus loin …</a></li>
</ul></li>
<li><a href="#les-évènements"><span class="toc-section-number">3.4.2</span> Les évènements</a></li>
<li><a href="#quelques-bonnes-pratiques"><span class="toc-section-number">3.4.3</span> Quelques bonnes pratiques</a><ul>
<li><a href="#pensez-performances"><span class="toc-section-number">3.4.3.1</span> Pensez performances :</a></li>
<li><a href="#soyez-sûr-que-les-éléments-de-votre-page-sont-tous-chargés"><span class="toc-section-number">3.4.3.2</span> Soyez sûr que les éléments de votre page sont tous chargés :</a></li>
</ul></li>
</ul></li>
<li><a href="#jouons-avec-underscore"><span class="toc-section-number">3.5</span> Jouons avec Underscore</a><ul>
<li><a href="#quelques-exemples-dutilisations"><span class="toc-section-number">3.5.1</span> Quelques exemples d'utilisations</a><ul>
<li><a href="#tableaux-et-collections"><span class="toc-section-number">3.5.1.1</span> Tableaux et Collections :</a></li>
<li><a href="#templating"><span class="toc-section-number">3.5.1.2</span> Templating :</a></li>
</ul></li>
</ul></li>
</ul></li>
<li><a href="#er-contact-avec-backbone"><span class="toc-section-number">4</span> 1er contact … avec Backbone</a><ul>
<li><a href="#ère-application-backbone"><span class="toc-section-number">4.1</span> 1ère application Backbone</a><ul>
<li><a href="#préparons-notre-page"><span class="toc-section-number">4.1.1</span> Préparons notre page</a></li>
</ul></li>
<li><a href="#le-modèle-article"><span class="toc-section-number">4.2</span> Le Modèle “Article”</a></li>
<li><a href="#la-collection-darticles"><span class="toc-section-number">4.3</span> La Collection d’Articles</a></li>
<li><a href="#vue-et-template"><span class="toc-section-number">4.4</span> Vue et Template</a><ul>
<li><a href="#quavons-nous-fait"><span class="toc-section-number">4.4.1</span> Qu’avons-nous fait ?</a></li>
</ul></li>
<li><a href="#un-dernier-tour-de-magie-pour-clôturer-le-chapitre-dinitiation-binding"><span class="toc-section-number">4.5</span> Un dernier tour de magie pour clôturer le chapitre d’initiation : “binding”</a><ul>
<li><a href="#que-venons-nous-de-faire"><span class="toc-section-number">4.5.1</span> Que venons-nous de faire ?</a></li>
<li><a href="#oh-la-vilaine-erreur"><span class="toc-section-number">4.5.2</span> Oh la vilaine erreur !!!</a></li>
</ul></li>
<li><a href="#code-final-de-lexemple"><span class="toc-section-number">4.6</span> Code final de l'exemple</a></li>
</ul></li>
<li><a href="#le-modèle-objet-de-backbone"><span class="toc-section-number">5</span> Le modèle objet de Backbone</a><ul>
<li><a href="#un-petit-tour-dans-le-code"><span class="toc-section-number">5.1</span> Un petit tour dans le code</a></li>
<li><a href="#ère-classe"><span class="toc-section-number">5.2</span> 1ère "classe"</a><ul>
<li><a href="#un-constructeur"><span class="toc-section-number">5.2.1</span> Un constructeur</a></li>
<li><a href="#des-propriétés"><span class="toc-section-number">5.2.2</span> Des propriétés</a></li>
<li><a href="#des-méthodes"><span class="toc-section-number">5.2.3</span> Des méthodes</a></li>
<li><a href="#des-membres-statiques"><span class="toc-section-number">5.2.4</span> Des membres statiques</a></li>
</ul></li>
<li><a href="#sans-héritage-point-de-salut"><span class="toc-section-number">5.3</span> Sans héritage point de salut ! … ?</a></li>
<li><a href="#surcharge-super"><span class="toc-section-number">5.4</span> Surcharge & super</a></li>
<li><a href="#conclusion"><span class="toc-section-number">5.5</span> Conclusion</a></li>
</ul></li>
<li><a href="#il-nous-faut-un-serveur"><span class="toc-section-number">6</span> Il nous faut un serveur !</a><ul>
<li><a href="#principes-http-get-post-put-delete"><span class="toc-section-number">6.1</span> Principes http : GET, POST, PUT, DELETE</a></li>
<li><a href="#installations"><span class="toc-section-number">6.2</span> Installation(s)</a><ul>
<li><a href="#installer-node.js"><span class="toc-section-number">6.2.1</span> Installer Node.js</a></li>
<li><a href="#installer-express.js"><span class="toc-section-number">6.2.2</span> Installer Express.js</a></li>
<li><a href="#installer-nstore"><span class="toc-section-number">6.2.3</span> Installer nStore</a></li>
</ul></li>
<li><a href="#codons-notre-application-serveur"><span class="toc-section-number">6.3</span> Codons notre application serveur</a><ul>
<li><a href="#ressources-statiques"><span class="toc-section-number">6.3.1</span> Ressources statiques</a></li>
<li><a href="#ressources-dynamiques"><span class="toc-section-number">6.3.2</span> Ressources dynamiques</a></li>
</ul></li>
<li><a href="#testons-notre-application-serveur"><span class="toc-section-number">6.4</span> Testons notre application serveur</a><ul>
<li><a href="#ajoutons-un-enregistrement"><span class="toc-section-number">6.4.1</span> Ajoutons un enregistrement</a></li>
<li><a href="#obtenir-tous-les-enregistrements"><span class="toc-section-number">6.4.2</span> Obtenir tous les enregistrements</a></li>
<li><a href="#retrouver-un-enregistrement-particulier-par-sa-clé"><span class="toc-section-number">6.4.3</span> Retrouver un enregistrement particulier (par sa clé)</a></li>
<li><a href="#mettre-à-jour-un-enregistrement"><span class="toc-section-number">6.4.4</span> Mettre à jour un enregistrement</a></li>
<li><a href="#faire-une-requête"><span class="toc-section-number">6.4.5</span> Faire une requête</a></li>
<li><a href="#supprimer-un-enregistrement"><span class="toc-section-number">6.4.6</span> Supprimer un enregistrement</a></li>
</ul></li>
</ul></li>
<li><a href="#les-modèles-et-les-collections-en-détail"><span class="toc-section-number">7</span> Les modèles et les collections en détail</a><ul>
<li><a href="#fonctionnement-général"><span class="toc-section-number">7.1</span> Fonctionnement général</a></li>
<li><a href="#modèles"><span class="toc-section-number">7.2</span> Modèles</a><ul>
<li><a href="#définition-du-modèle"><span class="toc-section-number">7.2.1</span> Définition du modèle</a></li>
<li><a href="#getters-et-setters"><span class="toc-section-number">7.2.2</span> Getters et Setters</a></li>
<li><a href="#structure-dun-modèle"><span class="toc-section-number">7.2.3</span> Structure d'un modèle</a></li>
<li><a href="#méthodes-crud-du-modèle"><span class="toc-section-number">7.2.4</span> Méthodes “CRUD” du modèle</a><ul>
<li><a href="#méthodes-save-création-mise-à-jour"><span class="toc-section-number">7.2.4.1</span> Méthodes save() : création & mise à jour<br /></a></li>
<li><a href="#méthode-fetch-retrouver-un-modèle"><span class="toc-section-number">7.2.4.2</span> Méthode fetch() : retrouver un modèle<br /></a></li>
<li><a href="#méthode-destroy-supprimer-un-modèle-du-serveur"><span class="toc-section-number">7.2.4.3</span> Méthode destroy() : supprimer un modèle du serveur<br /></a></li>
</ul></li>
<li><a href="#evénements"><span class="toc-section-number">7.2.5</span> Evénements</a></li>
<li><a href="#constructeur-initialize"><span class="toc-section-number">7.2.6</span> Constructeur : initialize</a></li>
<li><a href="#augmenter-le-modèle-ajouter-des-valeurs-par-défaut-et-des-méthodes-au-modèle"><span class="toc-section-number">7.2.7</span> “Augmenter” le modèle : ajouter des valeurs par défaut et des méthodes au modèle</a></li>
<li><a href="#comment-détecter-quun-modèle-a-été-changé-par-quelquun-dautre"><span class="toc-section-number">7.2.8</span> Comment détecter qu’un modèle a été changé par quelqu’un d’autre ?</a></li>
</ul></li>
<li><a href="#collections"><span class="toc-section-number">7.3</span> Collections</a><ul>
<li><a href="#comment-ajouter-des-modèles-à-une-collection"><span class="toc-section-number">7.3.1</span> Comment ajouter des modèles à une collection</a></li>
<li><a href="#parcourir-les-modèles-dune-collection"><span class="toc-section-number">7.3.2</span> Parcourir les modèles d’une collection</a></li>
<li><a href="#filtrer-les-modèles-dune-collection"><span class="toc-section-number">7.3.3</span> Filtrer les modèles d’une collection</a></li>
<li><a href="#trouver-le-1er-modèle-dune-collection-correspondant-à-un-critère"><span class="toc-section-number">7.3.4</span> Trouver le 1er modèle d’une collection correspondant à un critère</a></li>
<li><a href="#autres-méthodes-de-la-collection"><span class="toc-section-number">7.3.5</span> Autres méthodes de la collection</a></li>
</ul></li>
<li><a href="#les-collections-parlent-au-serveur"><span class="toc-section-number">7.4</span> Les collections “parlent” au serveur</a><ul>
<li><a href="#charger-les-données"><span class="toc-section-number">7.4.1</span> Charger les données</a></li>
<li><a href="#requêtes"><span class="toc-section-number">7.4.2</span> Requêtes</a></li>
</ul></li>
<li><a href="#evénements-1"><span class="toc-section-number">7.5</span> Evénements</a></li>
</ul></li>
<li><a href="#vues-templating"><span class="toc-section-number">8</span> Vues & Templating</a><ul>
<li><a href="#préparons-le-terrain"><span class="toc-section-number">8.1</span> Préparons le terrain</a><ul>
<li><a href="#création-et-sauvegarde-des-modèles"><span class="toc-section-number">8.1.1</span> Création et sauvegarde des modèles</a></li>
</ul></li>
<li><a href="#ère-vue"><span class="toc-section-number">8.2</span> 1ère vue</a><ul>
<li><a href="#explications-utilisation"><span class="toc-section-number">8.2.1</span> Explications & utilisation</a></li>
</ul></li>
<li><a href="#maintenant-un-peu-de-magie-..."><span class="toc-section-number">8.3</span> Maintenant, un peu de magie ...</a><ul>
<li><a href="#sabonner-aux-événements"><span class="toc-section-number">8.3.1</span> S'abonner aux événements</a></li>
<li><a href="#sabonner-à-dautres-évènements-modèles"><span class="toc-section-number">8.3.2</span> S’abonner à d’autres évènements (modèles)</a></li>
<li><a href="#amélioration-finalisation-du-code"><span class="toc-section-number">8.3.3</span> Amélioration & Finalisation du code</a></li>
</ul></li>
<li><a href="#utilisation-du-templating-...-1ère-fois"><span class="toc-section-number">8.4</span> Utilisation du templating ... 1ère fois</a><ul>
<li><a href="#définition-de-notre-1er-template"><span class="toc-section-number">8.4.1</span> Définition de notre 1er template</a></li>
</ul></li>
<li><a href="#sous-vues"><span class="toc-section-number">8.5</span> Sous-vue(s)</a><ul>
<li><a href="#réorganisation-du-code-html"><span class="toc-section-number">8.5.1</span> Réorganisation du code html</a></li>
<li><a href="#création-modification-des-vues"><span class="toc-section-number">8.5.2</span> Création & Modification des vues</a></li>
<li><a href="#un-dernier-petit-réglage-tri-des-collections"><span class="toc-section-number">8.5.3</span> Un dernier petit réglage : tri des collections</a></li>
</ul></li>
<li><a href="#utilisation-dautres-moteurs-de-template"><span class="toc-section-number">8.6</span> Utilisation d’autre(s) moteur(s) de template</a><ul>
<li><a href="#redéfinissons-donc-nos-templates"><span class="toc-section-number">8.6.1</span> Redéfinissons donc nos templates</a></li>
</ul></li>
<li><a href="#gestion-des-événements-dans-les-vues"><span class="toc-section-number">8.7</span> Gestion des événements dans les vues</a></li>
<li><a href="#authentification-côté-serveur-les-utilisateurs"><span class="toc-section-number">8.8</span> Authentification (côté serveur) : les utilisateurs</a><ul>
<li><a href="#sauthentifier-se-déconnecter"><span class="toc-section-number">8.8.1</span> S’authentifier – Se déconnecter</a></li>
</ul></li>
<li><a href="#authentification-côté-client"><span class="toc-section-number">8.9</span> Authentification (côté client)</a><ul>
<li><a href="#formulaire-dauthentification"><span class="toc-section-number">8.9.1</span> Formulaire d’authentification</a></li>
<li><a href="#lobjet-backbone.view-login.view"><span class="toc-section-number">8.9.2</span> L’objet Backbone.View : Login.View</a></li>
<li><a href="#ajoutons-une-gestion-des-évènements"><span class="toc-section-number">8.9.3</span> Ajoutons une gestion des évènements</a></li>
<li><a href="#vérification"><span class="toc-section-number">8.9.4</span> Vérification</a></li>
</ul></li>
</ul></li>
<li><a href="#le-routeur"><span class="toc-section-number">9</span> Le Routeur</a><ul>
<li><a href="#modifions-notre-vue"><span class="toc-section-number">9.1</span> Modifions notre vue</a></li>
<li><a href="#création-du-routeur"><span class="toc-section-number">9.2</span> Création du routeur</a></li>
</ul></li>
<li><a href="#organiser-son-code"><span class="toc-section-number">10</span> Organiser son code</a><ul>
<li><a href="#a-lancienne"><span class="toc-section-number">10.1</span> "A l'ancienne"</a><ul>
<li><a href="#namespace"><span class="toc-section-number">10.1.1</span> Namespace</a></li>
<li><a href="#modules"><span class="toc-section-number">10.1.2</span> Modules</a></li>
<li><a href="#au-final-nous-aurons-..."><span class="toc-section-number">10.1.3</span> Au final, nous aurons ...</a></li>
</ul></li>
<li><a href="#méthode-hype-comme-les-vrais"><span class="toc-section-number">10.2</span> Méthode “hype”, comme les vrais</a><ul>
<li><a href="#préparation"><span class="toc-section-number">10.2.1</span> Préparation</a></li>
</ul></li>
</ul></li>
<li><a href="#securisation"><span class="toc-section-number">11</span> Securisation</a><ul>
<li><a href="#il-nous-faut-un-écran-dadministration"><span class="toc-section-number">11.1</span> Il nous faut un "écran d’administration"</a><ul>
<li><a href="#création-dadminview"><span class="toc-section-number">11.1.1</span> Création d'AdminView</a></li>
<li><a href="#modification-de-loginview"><span class="toc-section-number">11.1.2</span> Modification de LoginView</a></li>
</ul></li>
<li><a href="#sécurisation-côté-serveur"><span class="toc-section-number">11.2</span> Sécurisation côté serveur</a><ul>
<li><a href="#sécurisation-des-routes"><span class="toc-section-number">11.2.1</span> Sécurisation des routes</a></li>
<li><a href="#eh-bien-testons-maintenant"><span class="toc-section-number">11.2.2</span> Eh bien testons, maintenant</a></li>
</ul></li>
</ul></li>
<li><a href="#backbone.sync"><span class="toc-section-number">12</span> Backbone.sync()</a></li>
<li><a href="#backbone-3-coffeescript"><span class="toc-section-number">13</span> Backbone <3 Coffeescript</a><ul>
<li><a href="#coffeescript-quest-ce-que-cest"><span class="toc-section-number">13.1</span> Coffeescript qu’est-ce que c’est ?</a></li>
<li><a href="#un-code-plus-lisible"><span class="toc-section-number">13.2</span> Un code plus lisible ?</a><ul>
<li><a href="#les-fonctions"><span class="toc-section-number">13.2.1</span> Les fonctions</a></li>
<li><a href="#interopérabilité"><span class="toc-section-number">13.2.2</span> Interopérabilité</a></li>
<li><a href="#interpolation-et-chaînes-de-caractères"><span class="toc-section-number">13.2.3</span> Interpolation et Chaînes de caractères</a></li>
<li><a href="#jouez-un-peu-avec-les-tableaux"><span class="toc-section-number">13.2.4</span> Jouez un peu avec les tableaux</a></li>
</ul></li>
<li><a href="#et-enfin-et-surtout-les-classes"><span class="toc-section-number">13.3</span> Et enfin (et surtout ?) les classes</a><ul>
<li><a href="#notre-1ère-classe"><span class="toc-section-number">13.3.1</span> Notre 1ère classe</a></li>
<li><a href="#propriétés-valeurs-par-défaut"><span class="toc-section-number">13.3.2</span> Propriétés & valeurs par défaut</a></li>
<li><a href="#comme-en-java-composition-association-encapsulation"><span class="toc-section-number">13.3.3</span> Comme en Java : Composition, Association, Encapsulation</a></li>
<li><a href="#comme-en-java-les-membres-statiques"><span class="toc-section-number">13.3.4</span> Comme en Java : les membres statiques</a></li>
<li><a href="#mais-aussi-comme-en-java-lhéritage"><span class="toc-section-number">13.3.5</span> Mais aussi (comme en Java) : l’héritage !</a></li>
</ul></li>
<li><a href="#jaime-je-naime-pas"><span class="toc-section-number">13.4</span> J’aime / Je n’aime pas</a></li>
<li><a href="#ré-écriture-de-notre-blog-soutiller"><span class="toc-section-number">13.5</span> Ré-écriture de notre blog ?! S'outiller</a><ul>
<li><a href="#installation-de-coffeescript"><span class="toc-section-number">13.5.1</span> Installation de Coffeescript</a></li>
<li><a href="#industrialisation-de-la-transpilation"><span class="toc-section-number">13.5.2</span> “Industrialisation” de la transpilation</a></li>
</ul></li>
<li><a href="#ré-écriture-traductions"><span class="toc-section-number">13.6</span> Ré-écriture / Traductions</a><ul>
<li><a href="#blog.coffee"><span class="toc-section-number">13.6.1</span> Blog.coffee</a></li>
<li><a href="#main.coffee"><span class="toc-section-number">13.6.2</span> main.coffee</a></li>
<li><a href="#post.coffee"><span class="toc-section-number">13.6.3</span> post.coffee</a></li>
<li><a href="#adminview.coffee"><span class="toc-section-number">13.6.4</span> AdminView.coffee</a></li>
<li><a href="#loginview.coffee"><span class="toc-section-number">13.6.5</span> LoginView.coffee</a></li>
<li><a href="#postslistview.coffee"><span class="toc-section-number">13.6.6</span> PostsListView.coffee</a></li>
<li><a href="#postview.coffee"><span class="toc-section-number">13.6.7</span> PostView.coffee</a></li>
<li><a href="#sidebarview.coffee"><span class="toc-section-number">13.6.8</span> SidebarView.coffee</a></li>
<li><a href="#mainview.coffee"><span class="toc-section-number">13.6.9</span> MainView.coffee</a></li>
<li><a href="#routes.coffee"><span class="toc-section-number">13.6.10</span> routes.coffee</a></li>
<li><a href="#transpilons"><span class="toc-section-number">13.6.11</span> Transpilons</a></li>
<li><a href="#conclusions"><span class="toc-section-number">13.6.12</span> Conclusion(s)</a></li>
</ul></li>
</ul></li>
<li><a href="#autres-frameworks-mvc"><span class="toc-section-number">14</span> Autres Frameworks MVC</a><ul>
<li><a href="#canjs"><span class="toc-section-number">14.1</span> CanJS</a><ul>
<li><a href="#mise-en-oeuvre-rapide"><span class="toc-section-number">14.1.1</span> Mise en oeuvre rapide</a></li>
<li><a href="#conclusion-sur-canjs"><span class="toc-section-number">14.1.2</span> Conclusion sur CanJS</a></li>
</ul></li>
<li><a href="#spine"><span class="toc-section-number">14.2</span> Spine</a><ul>
<li><a href="#mise-en-oeuvre-rapide-1"><span class="toc-section-number">14.2.1</span> Mise en oeuvre rapide</a></li>
<li><a href="#conclusion-sur-spine"><span class="toc-section-number">14.2.2</span> Conclusion sur Spine</a></li>
</ul></li>
<li><a href="#knockout"><span class="toc-section-number">14.3</span> Knockout</a><ul>
<li><a href="#mise-en-oeuvre-très-très-rapide-...-mais-suffisante"><span class="toc-section-number">14.3.1</span> Mise en oeuvre très très rapide ... Mais suffisante</a></li>
<li><a href="#un-modèle-selon-knockout"><span class="toc-section-number">14.3.2</span> Un modèle selon Knockout</a></li>
<li><a href="#collections-1"><span class="toc-section-number">14.3.3</span> Collections ?</a></li>
<li><a href="#attachons-notre-modèle-à-des-vues"><span class="toc-section-number">14.3.4</span> Attachons notre modèle à des vues !</a></li>
<li><a href="#attachons-note-liste-de-messages-à-une-vue"><span class="toc-section-number">14.3.5</span> Attachons note liste de messages à une vue</a></li>
<li><a href="#code-définitif-de-notre-page-index.html"><span class="toc-section-number">14.3.6</span> Code définitif de notre page index.html</a></li>
<li><a href="#démonstration"><span class="toc-section-number">14.3.7</span> Démonstration !!!</a></li>
<li><a href="#conclusion-1"><span class="toc-section-number">14.3.8</span> Conclusion</a></li>
</ul></li>
<li><a href="#encore-dautres-frameworks-mvc-javascript"><span class="toc-section-number">14.4</span> Encore d’autres frameworks MVC (javascript)</a></li>
<li><a href="#conclusion-2"><span class="toc-section-number">14.5</span> Conclusion</a></li>
</ul></li>
<li><a href="#backbone-et-typescript"><span class="toc-section-number">15</span> Backbone et Typescript</a><ul>
<li><a href="#typescript-on-installe"><span class="toc-section-number">15.1</span> TypeScript, on installe</a><ul>
<li><a href="#pré-requis"><span class="toc-section-number">15.1.1</span> Pré-requis</a></li>
<li><a href="#installation-de-typescript"><span class="toc-section-number">15.1.2</span> Installation de Typescript</a></li>
<li><a href="#comment-transpiler"><span class="toc-section-number">15.1.3</span> Comment transpiler ?</a></li>
<li><a href="#ide"><span class="toc-section-number">15.1.4</span> IDE ?</a></li>
<li><a href="#typescript-quoi-de-plus-que-javascript-ou-coffeescript"><span class="toc-section-number">15.1.5</span> TypeScript, quoi de plus que Javascript ou Coffeescript ?</a></li>
</ul></li>
<li><a href="#le-petit-tour-de-typescript-en-1-exemple"><span class="toc-section-number">15.2</span> Le (petit) tour de TypeScript en 1 exemple</a><ul>
<li><a href="#core.ts"><span class="toc-section-number">15.2.1</span> core.ts</a></li>
<li><a href="#allons-créer-nos-modèles"><span class="toc-section-number">15.2.2</span> Allons créer nos modèles</a></li>
<li><a href="#utilisons-tout-cela"><span class="toc-section-number">15.2.3</span> Utilisons tout cela</a></li>
</ul></li>
<li><a href="#et-backbone-dans-tout-ça"><span class="toc-section-number">15.3</span> Et Backbone dans tout ça ?</a></li>
</ul></li>
<li><a href="#ressources-backbone"><span class="toc-section-number">16</span> Ressources Backbone</a></li>
<li><a href="#resthub-backbone-stack"><span class="toc-section-number">17</span> RestHub Backbone Stack</a><ul>
<li><a href="#resthub-backbone-stack-mais-quest-ce-donc"><span class="toc-section-number">17.1</span> RESThub Backbone Stack : mais qu'est-ce donc ?</a></li>
<li><a href="#avant-de-sen-servir-nous-avons-besoin-dune-stack-serveur"><span class="toc-section-number">17.2</span> Avant de s'en servir, nous avons besoin d'une "stack serveur"</a></li>
<li><a href="#installation-de-rbs"><span class="toc-section-number">17.3</span> Installation de RBS</a></li>
<li><a href="#création-dun-modèle-et-dune-collection"><span class="toc-section-number">17.4</span> Création d'un modèle et d'une collection</a></li>
<li><a href="#templates"><span class="toc-section-number">17.5</span> Templates</a><ul>
<li><a href="#template-formulaire"><span class="toc-section-number">17.5.1</span> Template formulaire</a></li>
<li><a href="#template-de-liste"><span class="toc-section-number">17.5.2</span> Template de liste</a></li>
</ul></li>
<li><a href="#vues-associées-aux-templates"><span class="toc-section-number">17.6</span> Vues associées aux templates</a><ul>
<li><a href="#messages-view.js"><span class="toc-section-number">17.6.1</span> messages-view.js</a></li>
<li><a href="#message-form-view.js"><span class="toc-section-number">17.6.2</span> message-form-view.js</a></li>
</ul></li>
<li><a href="#app.js"><span class="toc-section-number">17.7</span> app.js</a></li>
<li><a href="#conclusion-3"><span class="toc-section-number">17.8</span> Conclusion</a></li>
</ul></li>
</ul>
</div>
<h1 id="préambule-remerciements"><a href="#TOC"><span class="header-section-number">1</span> Préambule & Remerciements</a></h1>
<p>J'ai eu la prétention d'écrire un livre, et sur Backbone en plus ! En fait il n'existe peu de littérature française spécialisée sur des frameworks, qui plus est des frameworks javascript, alors que nos amis anglo-saxons écrivent sur Dart, Coffeescript, Backbone, etc. ... Au départ ce "bouquin" est un projet un peu fou, puisque j'ai même contacté les éditions Eyrolles (quand je vous disais que j'étais prétentieux ;) ). Et ils ont été d'accord ! Alors vous vous demandez pourquoi, finalement je publie ça de manière open source ?</p>
<p>Eh bien, écrire un livre est un travail de longue haleine, qui doit se faire dans la durée. D'un autre côté, les technologies, tout particulièrement ce qui gravite autour de javascript, progressent et changent à une allure vertigineuse. Mon constat est que, si je veux écrire tout ce que j'ai en tête, cela ne finira jamais, ou bien le contenu n'aura plus d'intérêt (obsolète) et qu'il me semble plus approprié de livrer déjà ce que j'ai "gratté" et de transformer ce livre en projet open-source.</p>
<p>Ainsi, ceux qui souhaite se mettre à Backbone, peuvent commencer dès maintenant (même si on ne m'a pas attendu, j'imagine qu'un peu de documentation en français devrait faire des heureux). Pour les autres s'ils souhaitent compléter, corriger, modifier, discuter, je me tiens à leur disposition. C'est pour cela que j'ai publié le contenu sur Github = ainsi vous avez l'opportunité de faire des pull-requests (proposer des modifications) sur le contenu, ou créer des issues pour donner votre avis.</p>
<p>Je vous attends, j'espère que cela vous sera utile. Je m'adresse à tous les publics (les plus forts n'apprendront rien, mais peuvent contribuer). Ceux qui connaissent déjà Backbone peuvent directement passer au chapitre 04.</p>
<p>Je tiens à remercier très fortement et tout particulièrement, pour leur écoute, leurs conseils et leur relecture :</p>
<ul>
<li>Muriel SHANSEIFAN (Éditions Eyrolles - Responsable éditoriales du secteur informatique)</li>
<li>Laurène GIBAUD (Éditions Eyrolles - Secteur Informatique)</li>
</ul>
<p>Remerciements aussi pour :</p>
<ul>
<li><a href="https://github.com/ehsavoie">ehsavoie</a> : 1ère pull request ;)</li>
<li><a href="https://github.com/lodennan">lodennan</a></li>
<li><a href="https://github.com/cbonnissent">cbonnissent</a> : format epub</li>
<li><a href="https://github.com/loicdescotte">loicdescotte</a> : relecture & corrections</li>
<li><a href="https://github.com/hasalex">hasalex</a> : relecture & corrections (nombreuses)</li>
<li><a href="https://github.com/iammichiel">iammichiel</a> : typo</li>
<li><a href="https://github.com/sdeleuze">sdeleuze</a> : optimisation de code et typo</li>
</ul>
<h2 id="avertissement"><a href="#TOC"><span class="header-section-number">1.1</span> Avertissement</a></h2>
<p>Cet ouvrage est destiné à être purement éducatif. Donc le code n'est pas toujours fait dans les "règles de l'art", mais plutôt avec une "vision" pédagogique. Désolé donc pour les puristes, mais a priori vous n'êtes pas la cible ;). Cependant, je serais ravi de pouvoir inclure vos remarques et bonnes pratiques sous forme de notes dans chacun des chapitres. Donc à vos pull-requests !</p>
<h1 id="présentation-de-backbone-rappels-mvc"><a href="#TOC"><span class="header-section-number">2</span> Présentation de Backbone & rappels MVC</a></h1>
<blockquote>
<p><em>Sommaire</em></p>
</blockquote>
<blockquote>
<blockquote>
<ul>
<li><em>A quoi sert Backbone.js ?</em></li>
<li><em>Qu’est-ce qu’une « Webapp » ?</em></li>
<li><em>Petit rappel à propos de MVC</em></li>
</ul>
</blockquote>
</blockquote>
<blockquote>
<p><em>Où nous allons voir pourquoi Backbone existe et quels sont les grands principes qu’il met en œuvre.</em></p>
</blockquote>
<p>Ce chapitre est très court, il présente les origines de Backbone.js, le pourquoi de son utilisation, et enfin un rappel sur le patron de conception Modèle-Vue-Contrôleur, essentiel pour la bonne compréhension du framework.</p>
<h2 id="backbone-webapps-mvc"><a href="#TOC"><span class="header-section-number">2.1</span> Backbone ? Webapps ? MVC ?</a></h2>
<p>Backbone est un framework javascript dédié à la création de <strong>Webapps</strong> en mode <strong>"Single Page Application"</strong>. Il implémente le pattern MVC (l'acronyme signifie : Model View Controller / Modèle Vue Contrôleur) mais, et c'est là qu'est la nouveauté, côté client, plus précisément au sein de votre navigateur. Il reproduit les mécanismes des frameworks MVC côté serveur tels Ruby on Rails, CakePHP, Play!>Framework, ASP.Net MVC (avec Razor), ... Backbone a été écrit par Jeremy Ashkenas (le papa de Coffeescript et de Underscore) à l’origine pour ses propres besoins lors du développement du site DocumentCloud (<a href="http://www.documentcloud.org/home">http://www.documentcloud.org/home</a>). Son idée était de créer un framework qui permette de structurer ses développements en s’appuyant justement sur MVC. Mais avant toute chose, faisons quelques petits rappels (ou découvertes ?).</p>
<h3 id="quest-ce-quune-webapp"><a href="#TOC"><span class="header-section-number">2.1.1</span> Qu’est-ce qu’une “Webapp” ?</a></h3>
<p>Une “Webapp” n’a pas la même vocation qu’un site Web même si les technologies mises en œuvre sont les mêmes. Elle a une réelle valeur applicative (gestion de catalogue produits, utilitaires, client mails, agenda, etc. …) contrairement au site Web qui le plus souvent est un medium de communication (journaux, blogs, etc. …). Assez rapidement, les technologies Web ont été détournées pour tenter de remplacer les applications de gestion “client-riche” classique. Imaginez, le rêve des DSI : plus de déploiement, tout se passe dans le navigateur. Cependant, c’était compter sans les utilisateurs. Je me souviens avoir vu, il y a plus d'une dizaine d’années, une gestion de catalogue, en ASP 3 où à chaque création d’article, il fallait attendre que toute la liste des articles se recharge. Ce qui avant en mode texte (sous dos) prenait 1 minute, venait de prendre 3 à 5 minutes dans la vue : 3 à 5 fois plus de temps ! Bravo la productivité ! Ensuite les technologies se sont cherchées longtemps pour tenter de remédier à ce problème : utilisation des applets java (qui existaient depuis un moment), des ActiveX (MS qui veut faire comme Sun) et là on commençait à retomber dans les travers de déploiements compliqués. Puis il y eu Flash, Flex et Silverlight, pas mal du tout il faut l’avouer, mais parallèlement le moteur javascript avait évolué, les navigateurs aussi et avec l’avènement du triptyque HTML5 – CSS3 – Javascript, un nouveau concept est apparu la “Single Page Application” (probablement boosté par les mobiles et les tablettes … et Steve Jobs refusant que Flash/Air/Flex & Java s’installent sur l’iPhone & l’iPad). Mais qu’est donc une “Single Page Application” ? Il existe moult définitions, je vais donc vous donner la mienne, ensuite ce sera à vous de vous construire votre vision de “l’application Web monopage”.</p>
<p>Une "Single Page Application est une application Web qui embarque tous les éléments nécessaires à son fonctionnement dans une seule page HTML. Les scripts javascript liés seront chargés en même temps. Ensuite l’application Web chargera les ressources nécessaires (généralement des données, des images …) à la demande en utilisant Ajax évitant ainsi tout rechargement de page et procurant une expérience utilisateur proche de celle que nous connaissions en mode “client-serveur”, voire meilleure dans certains cas. Ces webapps nouvelle génération peuvent aussi fonctionner offline en profitant des possibilités des derniers navigateurs (localstorage).</p>
<blockquote>
<blockquote>
<p><strong>Remarque</strong> <em>: ce qui est amusant, c’est que dès 1999 ou 2000, Microsoft avait déjà introduit cette possibilité avec Internet Explorer 4 qui intégrait une applet Java (si si !) qui permettait de faire du Remote Protocol Call d’une page html vers le serveur sans recharger la page et en s’abonnant en javascript à l’évènement de retour (à vérifier, c’est loin, tout ça). Mais ce fut éclipsé par l’apparente simplicité de mise en œuvre des ActiveX (Flash était alors utilisé principalement pour de l’animation, mais permettait aussi ce genre d’artifice).</em></p>
</blockquote>
</blockquote>
<p>Tout ça c’est bien beau, mais vous savez comme moi qu’un code HTML+JS (+CSS) peut rapidement devenir un plat de spaghettis impossible à maintenir, pour les autres mais pour vous aussi (retournez dans votre code 6 mois plus tard ;)). Il faut donc s’astreindre à des règles et s’équiper des bons outils afin de se faciliter la tâche, ne pas avoir à réinventer la poudre à chaque fois et pouvoir coder des applications robustes facilement modifiables (faciles à corriger, faciles à faire évoluer). Et si en plus vous pouvez vous faire plaisir …</p>
<p>C’est de ce constat qu’est parti Jeremy Ashkenas, et c’est en mettant en pratique les préceptes depuis longtemps éprouvés de MVC qu’il a conçu Backbone, pour répondre à une problématique existante, ce qui le rend d’autant plus légitime. Rafraîchissons donc un peu notre mémoire à propos de MVC.</p>
<blockquote>
<blockquote>
<p><strong>Remarque</strong> <em>: pour les lecteurs qui ne connaitraient pas ce concept, ne refermez pas le livre tout de suite, vous verrez avec les exemples pratiques que le concept est simple et facilement assimilable. Donc si les quelques paragraphes théoriques qui suivent vous semblent obscurs, je vous promets que dans quelques chapitres vous aurez tout compris.</em></p>
</blockquote>
</blockquote>
<h3 id="petit-rappel-mvc"><a href="#TOC"><span class="header-section-number">2.1.2</span> Petit rappel : MVC ?</a></h3>
<p>MVC un pattern (modèle) de programmation utilisé pour développer des applications de manière structurée et organisée. Le pattern MVC, comme tous les patterns, cadre votre façon de développer. Son objectif particulier est de séparer les responsabilités de vos "bouts" de codes en les regroupant selon 3 rôles (responsabilités), donc le modèle, la vue et le contrôleur. Détaillons-les :</p>
<ul>
<li><strong>la vue</strong> : c'est l'IHM (Interface Homme-Machine), ce qui va apparaitre à l'écran de l'utilisateur. Elle va recevoir des infos du contrôleur ("affiche moi ça !"), elle va envoyer des infos au contrôleur ("on m'a cliquée dessus, il me faut la liste des clients")</li>
<li><strong>le contrôleur</strong> : c'est lui donc qui reçoit des infos de la vue, qui va aller récupérer des données métiers chez le modèle ("j'ai besoin pour la vue de la liste des clients"), et va les renvoyer à la vue et éventuellement appliquer des traitements à ces données avant de les renvoyer.</li>
<li><strong>le modèle</strong> : c'est votre objet client, fournisseur, utilisateur, ... avec toute la mécanique qui sert à les sauvegarder, les retrouver, modifier, supprimer ...</li>
</ul>
<blockquote>
<blockquote>
<p><strong>AVERTISSEMENT 1</strong> <em>: C’est la lisibilité qui importe. Il peut y avoir des interprétations différentes du modèle MVC quant aux responsabilités de ses composants. Par exemple, est-ce le modèle qui se sauvegarde lui-même ou est-ce un contrôleur qui se chargera de la persistance ? Peu importe (ce sont des querelles de chapelle), gardons juste à l'esprit qu'il y a trois grands modes de classement de nos objets et que l'important c'est d'avoir un code propre, structuré et maintenable (dans 6 mois, vous devez être capables de relire votre code).</em></p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><strong>AVERTISSEMENT 2</strong> <em>: La difficulté n’est plus de mise. A l'attention des réfugiés de STRUTS. Mon "1er contact" avec MVC a été avec STRUTS. J'ai trouvé l'expérience peu concluante (expérience développeur désastreuse) et je suis retourné faire de l'ASP.Net "à la souris" (c'était avant 2005). Si certains d'entre vous se sont éloignés de la technique et ont des velléités de s'y remettre mais sont effrayés par MVC, je les rassure tout de suite, les développeurs nous ont enfin "concoctés" des frameworks simples et faciles à mettre en œuvre tels :</em></p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<ul>
<li><em>ASP.Net MVC avec le moteur de template Razor</em></li>
<li><em>Play!>Framework</em></li>
<li><em>Express.js (avec nodeJS)</em></li>
<li><em>Et beaucoup d'autres</em></li>
</ul>
</blockquote>
</blockquote>
<p><em>Backbone.js respecte ce principe. Donc n'ayez pas peur, cela va être facile ;)</em></p>
<p>L'interprétation de MVC par Backbone est un peu particulière et les développeurs Java, .Net, PHP, Ruby, Python etc. pourraient être surpris. Mais, passons donc à quelques explications.</p>
<h2 id="backbone-mvc"><a href="#TOC"><span class="header-section-number">2.2</span> Backbone & MVC</a></h2>
<p>Backbone "embarque" plusieurs composants qui vont nous permettre d'organiser notre webapp selon les "préceptes" MVC et simplifier les communications avec le serveur (avec le code applicatif côté serveur).</p>
<p>Voyons l'interprétation que fait Backbone du modèle MVC :</p>
<ul>
<li>Le composant <strong>Modèle</strong> (selon Backbone : <code>Backbone.Model</code>) représente les données qui vont interagir avec votre code "backend" (côté serveur) via des requêtes Ajax. Ce sont eux qui auront la responsabilité de la logique métier et de la validation des données.</li>
<li>Le composant <strong>Vue</strong> (selon Backbone : <code>Backbone.View</code>) n'est pas complètement une vue au sens où on l'entend habituellement (couche présentation). Dans le cas qui nous intéresse, la "vraie" vue est un fragment de code "natif" HTML dans la page Web qui s'affiche dans le navigateur (il y a donc plusieurs vues dans une même page). Et <code>Backbone.View</code> est en fait un <strong>Contrôleur de vues</strong> (1) (vous verrez, ce sera plus facile à appréhender en le codant) qui va ordonnancer les évènements et interactions au sein de la page Web.</li>
</ul>
<blockquote>
<blockquote>
<p><em>(1) : c'est une interprétation très personnelle, c'est discutable, je reste à votre disposition</em></p>
</blockquote>
</blockquote>
<p>Pour résumer, avec un parallèle avec du MVC dit "classique", nous avons :</p>
<ul>
<li>Modèle : <code>Backbone.Model</code></li>
<li>Vue : le code HTML</li>
<li>Contrôleur (de vues) : <code>Backbone.View</code></li>
</ul>
<p><strong>Mais ce n'est pas fini !</strong> Backbone apporte 3 composants supplémentaires :</p>
<ul>
<li>Le composant <strong>Routeur</strong> : <code>Backbone.Router</code>, qui écoute/surveille les changements d'URL (dans la barre d'url du navigateur, lors d'un clic sur un lien, ...) et qui fait le lien avec les <code>Backbone.Model(s)</code> et les <code>Backbone.View(s)</code>.</li>
<li>Le composant <strong>Collection</strong> : <code>Backbone.Collection</code>, des collections de modèles avec des méthodes pour "travailler" avec ceux-ci (each, filter, map, ...)</li>
<li>et enfin le petit dernier, mais non des moindres, Le composant de <strong>Synchronisation</strong> <code>Backbone.sync</code>, que l'on pourrait comparer à une couche middleware, qui va permettre à nos modèles de communiquer avec le serveur. C'est <code>Backbone.sync</code> qui va faire les requêtes Ajax au serveur et "remonter" les résultats aux modèles.</li>
</ul>
<p><img src="RSRC/01_01_MVC.png" alt="Figure 1-1. MVC Vision "Back-End"" /> </p>
<p><strong><em>Figure 1-1. MVC Vision "Back-End"</em></strong></p>
<p><img src="RSRC/01_02_MVC.png" alt="Figure 1-2. MVC Vision "Front-End"" /> </p>
<p><strong><em>Figure 1-2. MVC Vision "Front-End"</em></strong></p>
<h2 id="pourquoi-jai-choisi-backbone"><a href="#TOC"><span class="header-section-number">2.3</span> Pourquoi j’ai choisi Backbone ?</a></h2>
<pre><code>//TODO:</code></pre>
<p>Tout ceci vous paraît bien théorique ? Alors passons tout de suite à la pratique.</p>
<h1 id="tout-de-suite-les-mains-dans-le-cambouis"><a href="#TOC"><span class="header-section-number">3</span> Tout de suite “les mains dans le cambouis”</a></h1>
<blockquote>
<p><em>Sommaire</em></p>
</blockquote>
<blockquote>
<blockquote>
<ul>
<li><em>Les prérequis & IDE pour faire fonctionner Backbone</em></li>
<li><em>jQuery en 15 minutes</em></li>
<li><em>Underscore.js en 10 minutes</em></li>
</ul>
</blockquote>
</blockquote>
<blockquote>
<p><em>Où nous allons lister les éléments nécessaires pour installer Backbone et commencer à développer avec.</em></p>
</blockquote>
<p>Le plus frustrant lorsque l'on débute la lecture d'un ouvrage informatique dans l'optique de s'auto former c'est que l'on est obligé de lire de nombreux chapitres avant de pouvoir commencer à s'y mettre. Je vais donc tenter de vous faire faire un 1er tour de Backbone.js en 20 minutes pour que vous en saisissiez rapidement la "substantifique moelle". Mais avant d’utiliser Backbone, quelques prérequis sont nécessaires. </p>
<h2 id="prérequis-les-dépendances-de-backbone"><a href="#TOC"><span class="header-section-number">3.1</span> Prérequis : les dépendances de Backbone</a></h2>
<p>Backbone a besoin au minimum de deux autres frameworks javascript pour fonctionner :</p>
<ul>
<li><strong>Underscore.js</strong> par le créateur de Backbone. Underscore est un ensemble d'outils qui permettent d'étendre javascript et qui vont vous faciliter la vie dans la gestion des Collections, Arrays, Objects, ... mais aussi vous permettre de faire du templating (nous verrons ce que c'est plus loin). Le gros avantage d'Underscore; c'est qu'il fonctionne quel que soit votre navigateur (comme Backbone). Underscore est une dépendance de Backbone, il est donc indispensable.</li>
<li><strong>jQuery</strong>, qui est un framework dédié à la manipulation des éléments de votre page HTML (on parlera du DOM, Document Object Model) mais aussi aux appels de type Ajax (nécessaire pour "discuter" avec le serveur). On peut dire que jQuery est un DSL (Domain Specific Language) pour le DOM. jQuery n'est pas indispensable pour faire fonctionner Backbone, mais il va grandement nous faciliter la vie dans la création de nos Webapps et va nous garantir le fonctionnement de notre code quel que soit le navigateur.</li>
</ul>
<p>Nous verrons dans quelques chapitres qu'il est tout à fait possible de "marier" d'autres frameworks javascript à Backbone pour :</p>
<ul>
<li>faire du templating (certains peuvent trouver la fonctionnalité de template d'Underscore limitée)</li>
<li>gérer la persistance locale (localstorage du navigateur)</li>
<li>...</li>
</ul>
<blockquote>
<blockquote>
<p><strong>Remarque :</strong> <em>Il est possible d'utiliser Zepto.js à la place de jQuery, Zepto fonctionne à l'identique de jQuery mais il est dédié principalement aux navigateurs mobiles et est beaucoup plus léger que jQuery (avantageux sur un mobile), cependant vous n'avez plus la garantie que votre code fonctionne dans d'autres navigateurs (Zepto "marchera" très bien sous Chrome, Safari et Firefox).</em></p>
</blockquote>
</blockquote>
<h2 id="outils-de-développement"><a href="#TOC"><span class="header-section-number">3.2</span> Outils de développement</a></h2>
<h3 id="ide-editeur"><a href="#TOC"><span class="header-section-number">3.2.1</span> IDE (Editeur)</a></h3>
<p>Pour coder choisissez l'éditeur de code avec lequel vous vous sentez le plus à l'aise. Ils ont tous leurs spécificités, ils sont gratuits, open-source ou payants. Certains "puristes" utilisent même Vim ou Emacs. Je vous en livre ici quelques-uns que j'ai trouvés agréables à utiliser si vous n'avez pas déjà fait votre choix :</p>
<ul>
<li>Mon préféré mais payant : WebStorm de chez JetBrains, il possède des fonctionnalités de refactoring très utiles (existe sous Windows, Linux et OSX)</li>
<li>Dans le même esprit et gratuit : Netbeans, il propose un éditeur HTML/Javascript très pertinent quant à la qualité de votre code (existe sous Windows, Linux et OSX)</li>
<li>Textmate (payant) un éditeur de texte avec colorisation syntaxique, un classique sous OSX</li>
<li>SublimeText (payant) un peu l'équivalent de Textmate mais toutes plateformes</li>
<li>Un bon compromis est KomodoEdit dans sa version communauté (donc non payant) et qui lui aussi fonctionne sur toutes les plateformes.</li>
<li>Aptana fourni aussi un bon IDE dédié Javascript sur une base Eclipse, mais je trouve qu'il propose finalement trop de fonctionnalités (comme Eclipse), et personnellement je m’y perds.</li>
</ul>
<p>Vous voyez, il y en a pour tous les goûts. En ce qui me concerne j'utilise essentiellement WebStorm ou SublimeText.</p>
<h3 id="navigateur"><a href="#TOC"><span class="header-section-number">3.2.2</span> Navigateur</a></h3>
<p>Le navigateur le plus agréable, selon moi, à utiliser pour faire du développement Web est certainement Chrome (c'est un avis très personnel, donc amis utilisateurs de Firefox ne m'en veuillez pas). En effet Chrome propose une console d'administration particulièrement puissante. C'est ce que je vais utiliser, rien ne vous empêche d'utiliser votre navigateur préféré. Par contre, que cela ne vous dispense pas d'aller tester régulièrement votre code sous d'autres navigateurs.</p>
<h2 id="initialisation-de-notre-projet-de-travail"><a href="#TOC"><span class="header-section-number">3.3</span> Initialisation de notre projet de travail</a></h2>
<p>Maintenant que nous sommes “outillés” (un éditeur de code et un navigateur) nous allons pouvoir initialiser notre environnement de développement.</p>
<h3 id="installation"><a href="#TOC"><span class="header-section-number">3.3.1</span> Installation</a></h3>
<ul>
<li>Créer un répertoire de travail <code>backbone001</code></li>
<li>Créer ensuite un sous-répertoire <code>libs</code> avec un sous-répertoire <code>vendors</code></li>
</ul>
<p>Nous copierons les frameworks javascript dans <code>vendors</code>.</p>
<ul>
<li>Téléchargez <strong>Backbone</strong> : <a href="http://documentcloud.github.com/backbone/">http://documentcloud.github.com/backbone/</a></li>
<li>Téléchargez <strong>Underscore</strong> : <a href="http://documentcloud.github.com/underscore/">http://documentcloud.github.com/underscore/</a></li>
</ul>
<blockquote>
<blockquote>
<p><strong>CONSEIL</strong> <em>: Utilisez les version non minifiées des fichiers. Il est toujours intéressant de pouvoir lire le code source des frameworks lorsqu'ils sont bien documentés, ce qui est le cas de Backbone et Underscore, n'hésitez pas à aller mettre le nez dedans, c'est instructif et ces 2 frameworks sont très lisibles, même pour des débutants.</em></p>
</blockquote>
</blockquote>
<ul>
<li>Téléchargez <strong>jQuery</strong> : <a href="http://jquery.com/">http://jquery.com/</a></li>
</ul>
<p>Nous allons aussi récupérer le framework css <strong>TwitterBootstrap</strong> qui nous permettra de faire de "jolies" pages sans effort. Ce n'est pas du tout obligatoire, mais c'est toujours plus satisfaisant d'avoir une belle page d'exemple. : <a href="http://twitter.github.com/bootstrap/">http://twitter.github.com/bootstrap/</a>. Téléchargez <code>bootstrap.zip</code>, "dé-zippez" le fichier et copiez le répertoire <code>bootstrap</code> dans votre répertoire <code>vendors</code>.</p>
<h3 id="préparons-notre-page-html"><a href="#TOC"><span class="header-section-number">3.3.2</span> Préparons notre page HTML</a></h3>
<p>A la racine de votre répertoire de travail, créez une page index.html avec le code suivant :</p>
<pre class="sourceCode html"><code class="sourceCode html"> <span class="dt"><!DOCTYPE </span>html<span class="dt">></span>
<span class="kw"><html></span>
<span class="kw"><head></span>
<span class="kw"><meta</span><span class="ot"> http-equiv=</span><span class="st">"Content-Type"</span><span class="ot"> content=</span><span class="st">"text/html; charset=utf-8"</span><span class="kw">></span>
<span class="kw"><title></span>Backbone<span class="kw"></title></span>
<span class="co"><!-- === Styles Twitter Bootstrap --></span>
<span class="kw"><link</span><span class="ot"> href=</span><span class="st">"libs/vendors/bootstrap/css/bootstrap.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="kw">></span>
<span class="kw"><link</span><span class="ot"> href=</span><span class="st">"libs/vendors/bootstrap/css/bootstrap-responsive.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="kw">></span>
<span class="kw"></head></span>
<span class="co"><!-- === ici votre IHM === --></span>
<span class="kw"><body></span>
<span class="kw"></body></span>
<span class="co"><!-- === Références aux Frameworks === --></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"libs/vendors/jquery-1.7.2.js"</span><span class="kw">></script></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"libs/vendors/underscore.js"</span><span class="kw">></script></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"libs/vendors/backbone.js"</span><span class="kw">></script></span>
<span class="co"><!-- === ici votre code applicatif === --></span>
<span class="kw"><script></span>
<span class="kw"></script></span>
<span class="kw"></html></span></code></pre>
<p>A ce niveau, vous devriez avoir un squelette de projet fonctionnel avec l'arborescence suivante :</p>
<p><img src="RSRC/02_01_ARBO.png" alt="Arborecsence" /><br /></p>
<p>Les deux paragraphes qui suivent ne sont que pour ceux d'entre vous qui ne connaissent ni <strong>jQuery</strong> ni <strong>Underscore</strong>. Ces paragraphes n'ont pas la prétention de vous apprendre ces outils, mais vous donneront les bases nécessaires pour vous en servir, pour comprendre leur utilité et pour vous donner envie d'aller plus loin. Les autres (ceux qui connaissent déjà), passez directement au <strong>§ "1er contact … avec Backbone"</strong>.</p>
<h2 id="jouons-avec-jquery"><a href="#TOC"><span class="header-section-number">3.4</span> Jouons avec jQuery</a></h2>
<p>JQuery est un framework javascript initialement créé par John Resig qui vous permet de prendre le contrôle de votre page HTML. Voyons tout de suite comment nous en servir. Dans notre toute nouvelle page <code>index.html</code>, préparons un peu notre bac à sable et saisissons le code suivant :</p>
<pre class="sourceCode html"><code class="sourceCode html"> <span class="dt"><!DOCTYPE </span>html<span class="dt">></span>
<span class="kw"><html></span>
<span class="kw"><head></span>
<span class="kw"><meta</span><span class="ot"> http-equiv=</span><span class="st">"Content-Type"</span><span class="ot"> content=</span><span class="st">"text/html; charset=utf-8"</span><span class="kw">></span>
<span class="kw"><title></span>Backbone<span class="kw"></title></span>
<span class="co"><!-- === Styles Twitter Bootstrap --></span>
<span class="kw"><link</span><span class="ot"> href=</span><span class="st">"libs/vendors/bootstrap/css/bootstrap.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="kw">></span>
<span class="co"><!-- === à insérer entre les 2 <link> === --></span>
<span class="kw"><style></span>
body <span class="kw">{</span>
<span class="kw">padding-top:</span> <span class="dt">60px</span><span class="kw">;</span>
<span class="co">/* </span>60<span class="co">px pour mettre un peu d</span>'<span class="co">espace entre la barre de titre et le contenu */</span>
<span class="kw">padding-bottom:</span> <span class="dt">40px</span><span class="kw">;</span>
<span class="kw">}</span>
<span class="kw"></style></span>
<span class="kw"><link</span><span class="ot"> href=</span><span class="st">"libs/vendors/bootstrap/css/bootstrap-responsive.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="kw">></span>
<span class="kw"></head></span>
<span class="co"><!-- === ici votre IHM === --></span>
<span class="kw"><body></span>
<span class="co"><!--</span>
<span class="co"> les classe css "navbar navbar-fixed-top", "navbar-inner", "container", </span>
<span class="co"> "brand", "jumbotron"</span>
<span class="co"> viennent de la feuille de style "twitter bootstrap "</span>
<span class="co"> --></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"navbar navbar-fixed-top"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"navbar-inner"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"container"</span><span class="kw">></span>
<span class="kw"><a</span><span class="ot"> class=</span><span class="st">"brand"</span><span class="kw">></span>Mon Blog<span class="kw"></a></span>
<span class="kw"></div></span>
<span class="kw"></div></span>
<span class="kw"></div></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"container"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"jumbotron"</span><span class="kw">></span>
<span class="kw"><h1></span>Backbone rocks !!!<span class="kw"></h1></span>
<span class="kw"><p></span>
"Ma vie mon oeuvre"
<span class="kw"></p></span>
<span class="kw"></div></span>
<span class="kw"><div</span><span class="ot"> id=</span><span class="st">"articles_box"</span><span class="kw">></span>
<span class="kw"><h1</span><span class="ot"> id=</span><span class="st">"current_articles_title"</span><span class="kw">></span>les articles du blogs<span class="kw"></h1></span>
<span class="kw"><ul</span><span class="ot"> id=</span><span class="st">"current_articles_list"</span><span class="kw">></span>
<span class="kw"><li></span>Backbone et les modèles<span class="kw"></li></span>
<span class="kw"><li></span>Backbone et les vues<span class="kw"></li></span>
<span class="kw"><li></span>Backbone : mais y a-t-il vraiment un contrôleur dans l'avion ?<span class="kw"></li></span>
<span class="kw"></ul></span>
<span class="kw"><h1</span><span class="ot"> id=</span><span class="st">"next_articles_title"</span><span class="kw">></span>les articles à venir<span class="kw"></h1></span>
<span class="kw"><ul</span><span class="ot"> id=</span><span class="st">"next_articles_list"</span><span class="kw">></span>
<span class="kw"><li></span>Backbone et le localstorage<span class="kw"></li></span>
<span class="kw"><li></span>Backbone.sync : comment ça marche<span class="kw"></li></span>
<span class="kw"></ul></span>
<span class="kw"></div></span>
<span class="kw"></div></span>
<span class="kw"></body></span>
<span class="co"><!-- === Références aux Frameworks === --></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"libs/vendors/jquery-1.7.2.js"</span><span class="kw">></script></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"libs/vendors/underscore.js"</span><span class="kw">></script></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"libs/vendors/backbone.js"</span><span class="kw">></script></span>
<span class="co"><!-- === ici votre code applicatif === --></span>
<span class="kw"><script></span>
<span class="kw"></script></span>
<span class="kw"></html></span></code></pre>
<p>Une fois votre page terminée, sauvegardez là et ouvrez là dans votre navigateur préféré (qui je le rappelle, pour des raisons purement pédagogique est Chrome) :</p>
<p><img src="RSRC/02_02_PAGE.png" alt="Page" /><br /> Notez au passage la qualité graphique de votre page ;), tout ça sans trop d'efforts, grâce à TwitterBootstrap.</p>
<h3 id="jouons-avec-notre-page-en-mode-commande"><a href="#TOC"><span class="header-section-number">3.4.1</span> "Jouons" avec notre page en mode commande</a></h3>
<p>Dans un premier temps, ouvrez la console de Chrome (ou Safari) : faite un clic droit sur la page et sélectionner "Inspect Element" (ou "Inspecter l'élément). Pour les aficionados de Firefox : utilisez les menus : Tools/Web Developer/Web Console. Vous devriez obtenir ceci (cliquez sur le bouton "Console" si nécessaire :</p>
<p><img src="RSRC/02_03_CONSOLE.png" alt="Console" /><br /></p>
<h4 id="saisissons-nos-1ères-commandes"><a href="#TOC"><span class="header-section-number">3.4.1.1</span> Saisissons nos 1ères commandes :</a></h4>
<p>Je voudrais la liste de mes titres <code><H1></code> : dans la console, saisir : <code>$('h1')</code>, validez, et vous obtenez un tableau (Array au sens javascript) des nodes html de type <code><H1></code> présentes dans votre page html :</p>
<p><img src="RSRC/02_04_JQUERY.png" alt="jQuery" /><br /></p>
<p>Je voudrais le texte de l'élément dont l'id est <code>"current_articles_title"</code> : dans la console, saisir : <code>$('#current_articles_title').text()</code>. L'identifiant étant unique, en fait le type de la node est peu important :</p>
<p><img src="RSRC/02_05_JQUERY.png" alt="jQuery" /><br /></p>
<p>Mais comment dois-je faire pour avoir le texte du premier <code><H1></code> de ma page, il n'a pas d'id ?!?. Tout simplement, en utilisant la commande suivante : <code>$('h1').first().text()</code> :</p>
<p><img src="RSRC/02_06_JQUERY.png" alt="jQuery" /><br /></p>
<h4 id="modifions-laspect-de-notre-page-dynamiquement"><a href="#TOC"><span class="header-section-number">3.4.1.2</span> Modifions l’aspect de notre page dynamiquement :</a></h4>
<p>Les commandes sont toujours à saisir dans la console du navigateur. Je voudrais :</p>
<ul>
<li>changer le titre de mon blog : <code>$('h1').first().text("Backbone c'est top !")</code>, attention pensez bien au <code>first()</code> sinon vous allez changer tous les textes de tous les <code>H1</code> de la page.</li>
<li>récupérer le code HTML de la "boîte de titre" (le div avec la classe css : <code>class="jumbotron"</code>) : <code>$('[class="jumbotron"]').html()</code>, notez bien que <code>$('[class="jumbotron"]').text()</code> ne retourne pas le même résultat. On peut aussi écrire ceci plus simplement : <code>$('.jumbotron').html()</code> : le <code>"."</code> correspond à une classe css, comme le <code>"#"</code> permet de rechercher un élément par son id.</li>
<li><p>changer les couleurs de police et de fond de tous les tags H1 :</p>
<p><code>$('h1').css("color","white").css("background-color","black")</code>, vous voyez que vous pouvez faire des appels chaînés, mais une autre possibilité serait la suivante :</p>
<pre><code> $('h1').css({color:"yellow", backgroundColor:"green"})</code></pre></li>
</ul>
<p><img src="RSRC/02_07_JQUERY.png" alt="jQuery" /><br /></p>
<p><img src="RSRC/02_08_JQUERY.png" alt="jQuery" /><br /></p>
<h4 id="allons-plus-loin"><a href="#TOC"><span class="header-section-number">3.4.1.3</span> Allons plus loin …</a></h4>
<p>Je voudrais :</p>
<ul>
<li>la valeur de l'id de la deuxième liste (<code>UL</code>) : <code>$('ul').eq(1).attr("id")</code>, je cherche la liste d'index 1 (le 1er élément possède l'index 0).</li>
<li>parcourir les lignes (<code>LI</code>) de la liste dont l'id est <code>"next_articles_list"</code> et obtenir leur texte : <code>$('#next_articles_list').find('li').each(function (index) { console.log( $(this).text() ); })</code></li>
<li><p>ajouter une nouvelle ligne à la 2ème liste :</p>
<pre><code>$('<li>Templating et Backbone</li>').appendTo('#next_articles_list')</code></pre></li>
<li>cacher la 1ère liste : <code>$('#current_articles_list').hide()</code></li>
<li>l'afficher à nouveau : <code>$('#current_articles_list').show()</code></li>
<li>la cacher à nouveau, mais "doucement" : <code>$('#current_articles_list').hide('slow')</code></li>
<li><p>l'afficher à nouveau, mais "rapidement" : <code>$('#current_articles_list').show('fast')</code></p></li>
</ul>
<p><img src="RSRC/02_09_JQUERY.png" alt="jQuery" /><br /></p>
<h3 id="les-évènements"><a href="#TOC"><span class="header-section-number">3.4.2</span> Les évènements</a></h3>
<pre><code>//À traiter ...</code></pre>
<h3 id="quelques-bonnes-pratiques"><a href="#TOC"><span class="header-section-number">3.4.3</span> Quelques bonnes pratiques</a></h3>
<h4 id="pensez-performances"><a href="#TOC"><span class="header-section-number">3.4.3.1</span> Pensez performances :</a></h4>
<p>Si vous devez utiliser plusieurs fois le même élément de votre page : par exemple <code>$('#current_articles_list')</code>, sachez qu'à chaque fois jQuery "interroge" le DOM. Pour des raisons de performances, il est conseillé d'affecter le résultat de la sélection à une variable que vous réutiliserez ensuite. De cette manière, le DOM n'est interrogé qu'une seule fois. Vous pouvez tester ceci dans la console :</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="kw">var</span> currArtList = $(<span class="ch">'#current_articles_list'</span>);
<span class="kw">currArtList</span>.<span class="fu">hide</span>(<span class="ch">'slow'</span>);
<span class="kw">currArtList</span>.<span class="fu">show</span>(<span class="ch">'fast'</span>);</code></pre>
<h4 id="soyez-sûr-que-les-éléments-de-votre-page-sont-tous-chargés"><a href="#TOC"><span class="header-section-number">3.4.3.2</span> Soyez sûr que les éléments de votre page sont tous chargés :</a></h4>
<p>Il est intéressant (indispensable) d'avoir la garantie que son code javascript n'est exécuté qu'une seule fois la page HTML chargée dans son entièreté, surtout si ce code accède à des éléments du DOM. jQuery a une fonction pour ça : <code>$(document).ready(handler)</code> ou encore plus court : <code>$(handler)</code> où <code>handler</code> est une fonction. Mettez ce code dans la balise <code><script></code> de votre page <code>index.html</code> :</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="kw">console</span>.<span class="fu">log</span>(<span class="st">"est-ce que le DOM est chargé ??? "</span>, $(<span class="ch">'#current_articles_list'</span>));
$(<span class="kw">function</span> (){
<span class="kw">console</span>.<span class="fu">log</span>(<span class="st">"je suis sûr que le DOM est chargé "</span>, $(<span class="ch">'#current_articles_list'</span>));
});</code></pre>
<p>Puis ouvrez la page dans votre navigateur et activez la console :</p>
<p><img src="RSRC/02_10_JQUERY.png" alt="jQuery" /><br /></p>
<p>Il semble que tous les éléments soient chargés correctement avec ou sans l’utilisation de la méthode <code>ready()</code> de jQuery. Vous avez du remarquer que j'avais déplacé mon code javascript et les références aux autres codes javascript "en bas de ma page". Maintenant, déplacez <code><script src="libs/vendors/jquery-1.7.2.js"></script></code> et le code source que nous avons écrit au niveau du header (balise <code><head></code>) de la page, ce qui est plus "classique" et rechargez la page :</p>
<p><img src="RSRC/02_11_JQUERY.png" alt="jQuery" /><br /></p>
<p>Et là on voit bien qu'au 1er appel <code>$('#current_articles_list')</code> jQuery ne trouve rien, puis une fois le DOM chargé, jQuery trouve la liste. J'ai mis mes codes en bas de page, pour des raisons de performances et c'est pour ça que cela "semblait" fonctionner même à l'extérieur de <code>$(document).ready(handler)</code>, les éléments se chargeant plus rapidement, mais ça ne garantit rien, tout particulièrement lorsque votre page n’est plus en local. Donc n'oubliez jamais d'exécuter votre code au bon moment grâce à <code>$(document).ready(handler)</code>, ... Et remettez quand même votre code en bas de page ;).</p>
<p>Vous venez de voir une infime partie des possibilités de jQuery, mais cela vous donne déjà un aperçu et vous permet de commencer à jouer avec et aller plus loin. jQuery permet aussi de faire des requêtes AJAX (http) vers des serveurs web, mais nous verrons cela un peu plus tard.</p>
<pre><code>//TODO: traiter la notion d’id versus la notion de name</code></pre>
<h2 id="jouons-avec-underscore"><a href="#TOC"><span class="header-section-number">3.5</span> Jouons avec Underscore</a></h2>
<p>Underscore est un framework javascript (par le créateur de Backbone) qui apporte de nombreuses fonctionnalités pour faire des traitements sur des tableaux de valeurs (Array) , des collections (tableaux d'objet). Certaines de ces fonctionnalités existent en javascript, mais uniquement dans sa dernière version, alors qu'avec Underscore vous aurez la garantie qu'elles s'exécutent sur tous les navigateurs. Mais Underscore, ce sont aussi des fonctionnalités autour des fonctions et des objets (là aussi, le framework vous procure les possibilités de la dernière version de javascript quel que soit votre navigateur ... ou presque, je n'ai pas testé sous IE6) et autres utilitaires, tels le templating. Je vous engage à aller sur le site, la documentation est particulièrement bien faite.</p>
<h3 id="quelques-exemples-dutilisations"><a href="#TOC"><span class="header-section-number">3.5.1</span> Quelques exemples d'utilisations</a></h3>
<p>Backbone utilise et encapsule de nombreuses fonctionnalités d'Underscore (Collection, modèle objet, ...) donc vous n'aurez pas forcément l'obligation d'utiliser Underscore directement. Je vous livre cependant quelques exemples, car cette puissante librairie peut vous aider sur d'autres projets pas forcément dédiés Backbone. Pour les tester, nous continuons avec la console de notre navigateur (toujours avec notre page index.html).</p>
<h4 id="tableaux-et-collections"><a href="#TOC"><span class="header-section-number">3.5.1.1</span> Tableaux et Collections :</a></h4>
<p>Commencez par saisir ceci :</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="kw">var</span> buddies = [],
bob = { <span class="dt">name </span>: <span class="st">"Bob Morane"</span>, <span class="dt">age </span>: <span class="dv">32</span> },
sam = { <span class="dt">name </span>: <span class="st">"Sammy"</span>, <span class="dt">age </span>: <span class="dv">43</span> },
tom = { <span class="dt">name </span>: <span class="st">"Tommy"</span>, <span class="dt">age </span>: <span class="dv">25</span> };
<span class="kw">buddies</span>.<span class="fu">push</span>(bob, sam, tom);</code></pre>
<p>Nous avons donc un tableau de 3 objets :</p>
<p><img src="RSRC/02_12_UNDERSCORE.png" alt="Underscore" /><br /></p>
<p>Je souhaite maintenant parcourir le tableau d’objets et afficher les informations de chacun d’eux. Pour cela utilisez la commande <code>each()</code> de la manière suivante :</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="kw">_</span>.<span class="fu">each</span>(buddies, <span class="kw">function</span> (buddy) {
<span class="kw">console</span>.<span class="fu">log</span> (<span class="kw">buddy</span>.<span class="fu">name</span>, <span class="kw">buddy</span>.<span class="fu">age</span>);
});</code></pre>
<p>Et vous obtiendrez ceci :</p>
<p><img src="RSRC/02_13_UNDERSCORE.png" alt="Underscore" /><br /></p>
<p>Je voudrais maintenant les “buddies” dont l’âge est inférieur à 43 ans. Nous allons utiliser la commande <code>filter()</code> :</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="kw">_</span>.<span class="fu">filter</span>(buddies, <span class="kw">function</span> (filteredBuddies) {
<span class="kw">return</span> <span class="kw">filteredBuddies</span>.<span class="fu">age</span> < <span class="dv">43</span>;
});</code></pre>
<p>Et nous obtenons bien :</p>
<p><img src="RSRC/02_14_UNDERSCORE.png" alt="Underscore" /><br /></p>
<h4 id="templating"><a href="#TOC"><span class="header-section-number">3.5.1.2</span> Templating :</a></h4>
<p>Je vous en parle maintenant, car ce "bijou" va nous servir très rapidement. Je voudrais générer une liste au sens HTML (<code><ul><li></li></ul></code>) à partir de mon tableau d'objets buddies. Nous allons donc créer une variable “template” (un peu comme une page JSP ou ASP) :</p>
<pre><code>var templateList =
"<ul> <% _.each(buddies, function (buddy) { %>\
<li><%= buddy.name %> : <%= buddy.age %> </li>\
<% }); %>\
</ul>";</code></pre>
<p>Que nous utiliserons de cette façon (nous passons à la méthode le template et les données):</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="kw">_</span>.<span class="fu">template</span>(templateList, buddies);</code></pre>
<p>Pour le résultat suivant :</p>
<p><img src="RSRC/02_15_UNDERSCORE.png" alt="Underscore" /><br /></p>
<p>Voilà, nous avons fait un rapide tour d’horizon des éléments qui nous seront nécessaires par la suite. Nous pouvons enfin commencer.</p>
<h1 id="er-contact-avec-backbone"><a href="#TOC"><span class="header-section-number">4</span> 1er contact … avec Backbone</a></h1>
<blockquote>
<p><em>Sommaire</em></p>
</blockquote>
<blockquote>
<blockquote>
<ul>
<li><em>Premier modèle</em></li>
<li><em>Première collection</em></li>
<li><em>Première vue & premier template</em></li>
</ul>
</blockquote>
</blockquote>
<blockquote>
<p><em>Nous allons faire un premier exemple Backbone pas à pas, même sans connaître le framework. Cela va permettre de « désacraliser » la bête et de mettre un peu de liant avec tout ce que nous avons vu précédemment. Puis nous passerons dans le détail tous les composants de Backbone dans les chapitres qui suivront.</em></p>
</blockquote>
<p>Voilà, il est temps de s'y mettre. L'application que nous allons réaliser avec Backbone tout au long de cet ouvrage va être un Blog, auquel nous ajouterons au fur et à mesure des fonctionnalités pour finalement le transformer en CMS (Content Management System). Je vous l'accorde ce n'est pas très original, mais cela répond à des problématiques classiques (récurrentes ?) dans notre vie "d'informaticien" et cela a le mérite d'avoir un aspect pratique et utile. Notre point de départ va être un blog que nous agrémenterons de fonctionnalités au fil des chapitres.</p>
<h2 id="ère-application-backbone"><a href="#TOC"><span class="header-section-number">4.1</span> 1ère application Backbone</a></h2>
<p>Nous allons faire ici un exemple très rapide, sans forcément entrer dans le détail ni mettre en œuvre les bonnes pratiques d'organisation de code. Cet exercice est là pour démontrer la simplicité d'utilisation, et le code devrait être suffisamment simple pour se passer d'explications. Donc, "pas de panique !", laissez-vous guider, dans <strong>15 minutes</strong> vous aurez une 1ère ébauche.</p>
<h3 id="préparons-notre-page"><a href="#TOC"><span class="header-section-number">4.1.1</span> Préparons notre page</a></h3>
<p>Nous allons utiliser notre même page <code>index.html</code>, mais faisons un peu de ménage à l'intérieur avant de commencer :</p>
<pre class="sourceCode html"><code class="sourceCode html"> <span class="dt"><!DOCTYPE </span>html<span class="dt">></span>
<span class="kw"><html></span>
<span class="kw"><head></span>
<span class="kw"><meta</span><span class="ot"> http-equiv=</span><span class="st">"Content-Type"</span><span class="ot"> content=</span><span class="st">"text/html; charset=utf-8"</span><span class="kw">></span>
<span class="kw"><title></span>Backbone<span class="kw"></title></span>
<span class="kw"><link</span><span class="ot"> href=</span><span class="st">"libs/vendors/bootstrap/css/bootstrap.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="kw">></span>
<span class="kw"><style></span>
body <span class="kw">{</span>
<span class="kw">padding-top:</span> <span class="dt">60px</span><span class="kw">;</span>
<span class="kw">padding-bottom:</span> <span class="dt">40px</span><span class="kw">;</span>
<span class="kw">}</span>
<span class="kw"></style></span>
<span class="kw"><link</span><span class="ot"> href=</span><span class="st">"libs/vendors/bootstrap/css/bootstrap-responsive.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="kw">></span>
<span class="kw"></head></span>
<span class="kw"><body></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"navbar navbar-fixed-top"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"navbar-inner"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"container"</span><span class="kw">></span>
<span class="kw"><a</span><span class="ot"> class=</span><span class="st">"brand"</span><span class="kw">></span>Mon Blog<span class="kw"></a></span>
<span class="kw"></div></span>
<span class="kw"></div></span>
<span class="kw"></div></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"container"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"jumbotron"</span><span class="kw">></span>
<span class="kw"><h1></span>Backbone rocks !!!<span class="kw"></h1></span>
<span class="kw"></div></span>
<span class="kw"></div></span>
<span class="kw"></body></span>
<span class="co"><!-- === Références aux Frameworks === --></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"libs/vendors/jquery-1.7.2.js"</span><span class="kw">></script></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"libs/vendors/underscore.js"</span><span class="kw">></script></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"libs/vendors/backbone.js"</span><span class="kw">></script></span>
<span class="kw"><script></span>
$(<span class="kw">function</span> (){
});
<span class="kw"></script></span>
<span class="kw"></html></span></code></pre>
<p>L'essentiel de notre travail va se passer dans la balise <code><script></script></code> en bas de page. De quoi avons-nous besoin dans un blog ?</p>
<ul>
<li>Des articles : un ensemble d'articles (ou "posts"), généralement écrits par une seule personne (le blog est personnel, c'est en lui donnant des fonctionnalités multi-utilisateurs que nous nous dirigerons doucement vers un CMS).</li>
<li>Des commentaires : Il est de bon ton de permettre aux lecteurs du blog de pouvoir commenter les articles.</li>
</ul>
<p>Pour le moment nous allons nous concentrer uniquement sur les articles, notre objectif sera le suivant : "Afficher une liste d'articles sur la page principale".</p>
<h2 id="le-modèle-article"><a href="#TOC"><span class="header-section-number">4.2</span> Le Modèle “Article”</a></h2>
<p>Dans la balise <code><script></script></code> saisissez le code suivant :</p>
<p><em>Définition d’un modèle Article :</em></p>
<pre class="sourceCode html"><code class="sourceCode html"> <span class="kw"><script></span>
$(<span class="kw">function</span> (){
<span class="co">//permettra d</span>'<span class="co">accéder à nos variables en mode console</span>
<span class="kw">window</span>.<span class="fu">blog</span> = {};
<span class="co">/*</span>--- Modèle article ---<span class="co">*/</span>
<span class="co">// une </span>"<span class="co">sorte</span>"<span class="co"> de classe Article</span>
<span class="kw">blog</span>.<span class="fu">Article</span> = <span class="kw">Backbone.Model</span>.<span class="fu">extend</span>({
<span class="co">//les valeurs par défaut d</span>'<span class="co">un article</span>
<span class="dt">defaults </span>: {
<span class="dt">title </span>: <span class="st">"titre</span> <span class="st">de</span> <span class="st">l</span>'<span class="st">article"</span>,
<span class="dt">content </span>: <span class="st">"contenu</span> <span class="st">de</span> <span class="st">l</span>'<span class="st">article"</span>,
<span class="dt">publicationDate </span>: <span class="kw">new</span> <span class="kw">Date</span>()
},
<span class="co">// s</span>'<span class="co">exécute à la création d</span>'<span class="co">un article</span>
<span class="dt">initialize </span>: <span class="kw">function</span> () {
<span class="kw">console</span>.<span class="fu">log</span> (<span class="st">"Création</span> <span class="st">d</span>'<span class="st">un</span> <span class="st">nouvel</span> <span class="st">article"</span>)
}
});
});
<span class="kw"></script></span></code></pre>
<p>Sauvegardez, relancez dans le navigateur, et allez dans la console :</p>
<ul>
<li>Pour créer un nouvel article : tapez la commande <code>myFirstArticle = new blog.Article()</code></li>
<li>Pour "voir" le titre de l'article : tapez la commande <code>myFirstArticle.get("title")</code></li>
<li>Pour "voir" le contenu de l'article : tapez la commande <code>myFirstArticle.get("content")</code></li>
<li>Pour changer le titre de l'article : tapez la commande <code>myFirstArticle.set("title","MON TITRE")</code> ou <code>myFirstArticle.set({title : "MON TITRE"})</code></li>
<li>Pour changer simultanément le titre et le contenu : tapez la commande <code>myFirstArticle.set({title : "MON TITRE ...", content : "blablabla"})</code></li>
<li>Pour créer un article directement avec un titre et du contenu : tapez la commande <code>mySecondArticle = new blog.Article({title : "MON AUTRE ARTICLE", content : "lore ipsum ..."})</code></li>
</ul>
<p><img src="RSRC/03_01_BB.png" alt="BB" /><br /></p>
<p>Vous venez donc de voir que nous avons défini le modèle article “un peu” comme une classe qui hériterait (<code>extend</code>) de la classe <code>Backbone.Model</code>, que nous lui avons défini des valeurs par défauts (<code>defaults</code>), et affecté une méthode d’initialisation (<code>initialize</code>). Et qu’il existe un système de getter et de setter un peu particulier (<code>model.get(property_name)</code>, <code>model.set(property_name, value)</code>), mais nous verrons ultérieurement dans le détail comment fonctionnent les modèles.</p>
<blockquote>
<blockquote>
<p><strong>Remarque</strong> <em>: le modèle de programmation de Javascript est bien orienté objet, mais n’est pas orienté “classe” comme peut l’être par exemple Java. Cela peut déstabiliser au départ, mais je vous engage à lire [REF VERS ARTICLE] à ce propos.</em></p>
</blockquote>
</blockquote>
<h2 id="la-collection-darticles"><a href="#TOC"><span class="header-section-number">4.3</span> La Collection d’Articles</a></h2>
<p>Nous allons maintenant définir une collection qui nous aidera à gérer nos articles. Donc, à la suite du modèle Article saisissez le code suivant :</p>
<p><em>Définition d’une collection d’articles :</em></p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="co">/*--- Collection d'articles ---*/</span>
<span class="kw">blog</span>.<span class="fu">ArticlesCollection</span> = <span class="kw">Backbone.Collection</span>.<span class="fu">extend</span>({
<span class="dt">model </span>: <span class="kw">blog</span>.<span class="fu">Article</span>,
<span class="dt">initialize </span>: <span class="kw">function</span> () {
<span class="kw">console</span>.<span class="fu">log</span> (<span class="st">"Création d'une collection d'articles"</span>)
}
});</code></pre>
<blockquote>
<blockquote>
<p><strong>Notez</strong> <em>qu'il faut bien préciser le type de modèle adressé par la collection (on pourrait dire que la collection est typée).</em></p>
</blockquote>
</blockquote>
<p>Sauvegarder, relancer dans le navigateur, et retournez à nouveau dans la console et saisissez les commandes suivantes :</p>
<ul>
<li><p>Création de la collection :</p>
<pre><code>listeArticles = new blog.ArticlesCollection()</code></pre></li>
<li><p>Ajout d’articles à la collection :</p>
<pre><code>listeArticles.add(new blog.Article({ title : "titre1", content : "contenu1" }))
listeArticles.add(new blog.Article({ title : "titre2", content : "contenu2" }))
listeArticles.add(new blog.Article({ title : "titre3", content : "contenu3" }))</code></pre></li>
</ul>
<p>Nous venons donc d'ajouter 3 articles à notre collection,</p>
<ul>
<li>Si vous tapez la commande <code>listeArticles.models</code> vous obtiendrez un tableau de modèles</li>
<li><p>Si vous souhaitez obtenir le titre du 2ème article de la collection, tapez :</p>
<p><code>listeArticles.models[1].get("title")</code></p></li>
<li><p>vous souhaitez parcourir les articles de la collection et afficher leur titre :</p>
<p><code>listeArticles.each(function(article){ console.log (article.get("title")); });</code></p></li>
</ul>
<blockquote>
<blockquote>
<p>Cela vous rappelle quelque chose ? Le <code>each</code> de Backbone est implémenté grâce à Underscore.</p>
</blockquote>
</blockquote>
<p><img src="RSRC/03_02_BB.png" alt="BB" /><br /></p>
<p><strong>Maintenant que nous avons de quoi gérer nos données, il est temps de les afficher dans notre page HTML.</strong></p>
<h2 id="vue-et-template"><a href="#TOC"><span class="header-section-number">4.4</span> Vue et Template</a></h2>
<p>Avant toute chose, allons ajouter dans notre code javascript (en bas de la page HTML) le bout de code qui va créer les articles et la collection d'articles pour nous éviter de tout re-saisir à chaque fois. Donc après le code de la collection, ajoutez ceci :</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="co">/*--- bootstrap ---*/</span>
<span class="kw">blog</span>.<span class="fu">listeArticles</span> = <span class="kw">new</span> <span class="kw">blog</span>.<span class="fu">ArticlesCollection</span>();
<span class="kw">blog.listeArticles</span>.<span class="fu">add</span>(<span class="kw">new</span> <span class="kw">blog</span>.<span class="fu">Article</span>({ <span class="dt">title </span>: <span class="st">"titre1"</span>, <span class="dt">content </span>: <span class="st">"contenu1"</span> }));
<span class="kw">blog.listeArticles</span>.<span class="fu">add</span>(<span class="kw">new</span> <span class="kw">blog</span>.<span class="fu">Article</span>({ <span class="dt">title </span>: <span class="st">"titre2"</span>, <span class="dt">content </span>: <span class="st">"contenu2"</span> }));
<span class="kw">blog.listeArticles</span>.<span class="fu">add</span>(<span class="kw">new</span> <span class="kw">blog</span>.<span class="fu">Article</span>({ <span class="dt">title </span>: <span class="st">"titre3"</span>, <span class="dt">content </span>: <span class="st">"contenu3"</span> }));
<span class="kw">blog.listeArticles</span>.<span class="fu">add</span>(<span class="kw">new</span> <span class="kw">blog</span>.<span class="fu">Article</span>({ <span class="dt">title </span>: <span class="st">"titre4"</span>, <span class="dt">content </span>: <span class="st">"contenu4"</span> }));
<span class="kw">blog.listeArticles</span>.<span class="fu">add</span>(<span class="kw">new</span> <span class="kw">blog</span>.<span class="fu">Article</span>({ <span class="dt">title </span>: <span class="st">"titre5"</span>, <span class="dt">content </span>: <span class="st">"contenu5"</span> }));</code></pre>
<p>Ensuite dans le code html, ajoutons le template de notre vue et le div dans lequel les données seront affichées :</p>
<pre class="sourceCode html"><code class="sourceCode html"> <span class="er"><</span>% _.each(articles, function(article) { %>
<span class="kw"><h1></span><span class="er"><</span>%= article.title %><span class="kw"></h1></span>
<span class="kw"><h6></span><span class="er"><</span>%= article.publicationDate %><span class="kw"></h6></span>
<span class="kw"><p></span><span class="er"><</span>%= article.content %><span class="kw"></p></span>
<span class="er"><</span>% }); %></code></pre>
<p>donc :</p>
<pre class="sourceCode html"><code class="sourceCode html"> <span class="kw"><body></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"navbar navbar-fixed-top"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"navbar-inner"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"container"</span><span class="kw">></span>
<span class="kw"><a</span><span class="ot"> class=</span><span class="st">"brand"</span><span class="kw">></span>Mon Blog<span class="kw"></a></span>
<span class="kw"></div></span>
<span class="kw"></div></span>
<span class="kw"></div></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"container"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"jumbotron"</span><span class="kw">></span>
<span class="kw"><h1></span>Backbone rocks !!!<span class="kw"></h1></span>
<span class="kw"></div></span>
<span class="co"><!-- ìci notre template --></span>
<span class="kw"><script</span><span class="ot"> type=</span><span class="st">"text/template"</span><span class="ot"> id=</span><span class="st">"articles-collection-template"</span><span class="kw">></span>
<% <span class="kw">_</span>.<span class="fu">each</span>(articles, <span class="kw">function</span>(article) { %>
<h1><%= <span class="kw">article</span>.<span class="fu">title</span> %></h1>
<h6><%= <span class="kw">article</span>.<span class="fu">publicationDate</span> %></h6>
<p><%= <span class="kw">article</span>.<span class="fu">content</span> %></p>
<% }); %>
<span class="kw"></script></span>
<span class="co"><!-- les données seront affichées ici --></span>
<span class="kw"><div</span><span class="ot"> id=</span><span class="st">"articles-collection-container"</span><span class="kw">></div></span>
<span class="kw"></div></span>
<span class="kw"></body></span></code></pre>
<p>Puis dans le code javascript, à la suite du code de la collection et avant le code de chargement des données (bootstrap), ajoutez le code de la vue Backbone :</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="co">/*--- Vues ---*/</span>
<span class="kw">blog</span>.<span class="fu">ArticlesView</span> = <span class="kw">Backbone.View</span>.<span class="fu">extend</span>({
<span class="dt">el </span>: $(<span class="st">"#articles-collection-container"</span>),
<span class="dt">initialize </span>: <span class="kw">function</span> () {
<span class="kw">this</span>.<span class="fu">template</span> = <span class="kw">_</span>.<span class="fu">template</span>($(<span class="st">"#articles-collection-template"</span>).<span class="fu">html</span>());
},
<span class="dt">render </span>: <span class="kw">function</span> () {
<span class="kw">var</span> renderedContent = <span class="kw">this</span>.<span class="fu">template</span>({ <span class="dt">articles </span>: <span class="kw">this</span>.<span class="fu">collection</span>.<span class="fu">toJSON</span>() });
$(<span class="kw">this</span>.<span class="fu">el</span>).<span class="fu">html</span>(renderedContent);
<span class="kw">return</span> <span class="kw">this</span>;
}
});</code></pre>
<h3 id="quavons-nous-fait"><a href="#TOC"><span class="header-section-number">4.4.1</span> Qu’avons-nous fait ?</a></h3>
<p>Eh bien, nous avons défini une vue avec :</p>
<ul>
<li><p>Une propriété <code>el</code> (pour élément) à laquelle on “attache” le <code><div></code> dont l’id est :</p>
<p><code>“articles-collection-container”</code>. C’est dans ce <code><div></code> que seront affichés les articles</p></li>
<li>Une méthode <code>initialize</code>, qui affecte une méthode <code>template()</code> à l’instance de la vue en lui précisant que nous utiliserons le modèle de code html définit dans le <code><div></code> dont l’id est <code>“articles-collection-template”</code></li>
<li><p>Une méthode <code>render</code>, qui va passer les données en paramètre à la méthode <code>template()</code> puis les afficher dans la page</p></li>
</ul>
<p>Sauvegarder, relancer dans le navigateur, et retournez encore dans la console pour saisir les commandes suivantes :</p>
<ul>
<li>Pour instancier une vue : <code>articlesView = new blog.ArticlesView({ collection : blog.listeArticles })</code> à laquelle nous passons la collection d’articles en paramètre</li>
<li>Pour afficher les données : <code>articlesView.render()</code></li>
</ul>
<p><strong>Et là la "magie" de Backbone s'opère, vos articles s'affichent instantanément dans votre page :</strong> :)</p>
<p><img src="RSRC/03_03_BB.png" alt="BB" /><br /></p>
<blockquote>
<blockquote>
<p><strong>Remarque</strong> : Notez bien que la collection doit être transformée en chaîne JSON pour être interprétée dans le template ( <code>this.template({ articles : this.collection.toJSON() })</code> ) et que nous avons nommé le paramètre <code>articles</code> pour faire le lien avec le template ( <code>_.each(articles, function(article) {}</code> ).</p>
</blockquote>
</blockquote>
<h2 id="un-dernier-tour-de-magie-pour-clôturer-le-chapitre-dinitiation-binding"><a href="#TOC"><span class="header-section-number">4.5</span> Un dernier tour de magie pour clôturer le chapitre d’initiation : “binding”</a></h2>
<p>A la fin de la méthode <code>initialize</code> de la vue, ajoutez le code suivant :</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="co">/*--- binding ---*/</span>
<span class="kw">_</span>.<span class="fu">bindAll</span>(<span class="kw">this</span>, <span class="ch">'render'</span>);
<span class="kw">this</span>.<span class="fu">collection</span>.<span class="fu">bind</span>(<span class="ch">'change'</span>, <span class="kw">this</span>.<span class="fu">render</span>);
<span class="kw">this</span>.<span class="fu">collection</span>.<span class="fu">bind</span>(<span class="ch">'add'</span>, <span class="kw">this</span>.<span class="fu">render</span>);
<span class="kw">this</span>.<span class="fu">collection</span>.<span class="fu">bind</span>(<span class="ch">'remove'</span>, <span class="kw">this</span>.<span class="fu">render</span>);
<span class="co">/*---------------*/</span></code></pre>
<h3 id="que-venons-nous-de-faire"><a href="#TOC"><span class="header-section-number">4.5.1</span> Que venons-nous de faire ?</a></h3>
<p>Nous venons "d'expliquer" à Backbone, qu'à chaque changement dans la collection, la vue doit rafraîchir son contenu. <code>_.bindAll</code> est une méthode d'Underscore (<a href="http://documentcloud.github.com/underscore/#bind">http://documentcloud.github.com/underscore/#bind</a>) qui permet de conserver le contexte initial, c'est à dire : quel que soit "l'endroit" d'où l'on appelle la méthode <code>render</code>, ce sera bien l'instance de la vue (attachée à <code>this</code>) qui sera utilisée.</p>
<pre><code>//TODO: à expliquer plus simplement</code></pre>
<p>Une dernière fois, sauvegarder, relancer le navigateur, et retournez encore dans la console pour saisir les commandes suivantes :</p>
<ul>
<li>Création de la vue : <code>articlesView = new blog.ArticlesView({ collection : blog.listeArticles })</code></li>
<li>Afficher les données : <code>articlesView.render()</code></li>
<li>Ajouter un nouvel article à la collection : <code>blog.listeArticles.add(new blog.Article({title:"Hello", content:"Hello World"}))</code></li>
</ul>
<p><strong>Et là, magique ! : L’affichage s'est actualisé tout seul :</strong></p>
<h3 id="oh-la-vilaine-erreur"><a href="#TOC"><span class="header-section-number">4.5.2</span> Oh la vilaine erreur !!!</a></h3>
<p>Si vous avez bien suivi, j'ai fait une grossière erreur (je l’ai laissé volontairement, car c'est une erreur que j'ai déjà faite, et il n'est donc pas impossible que d'autres la fassent), la date de publication ne change pas ! En effet, je l'affecte dans les valeurs par défaut qui ne sont "settées" qu'une seule et unique fois lors de la définition de la "pseudo" classe <code>Backbone.Model</code>. Il faut donc initialiser la date de publication lors de l'instanciation du modèle, et ce dans la méthode <code>initialize()</code>. Modifiez donc le code du modèle de la manière suivante :</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="co">/*--- Modèle article ---*/</span>
<span class="kw">blog</span>.<span class="fu">Article</span> = <span class="kw">Backbone.Model</span>.<span class="fu">extend</span>({ <span class="co">// une "sorte" de classe Article</span>
<span class="dt">defaults </span>: { <span class="co">//les valeurs par défaut d'un article</span>
<span class="dt">title </span>: <span class="st">"titre de l'article"</span>,
<span class="dt">content </span>: <span class="st">"contenu de l'article"</span>,
<span class="co">//publicationDate : null</span>
},
<span class="dt">initialize </span>: <span class="kw">function</span> () { <span class="co">// s'exécute à la création d'un article</span>
<span class="kw">console</span>.<span class="fu">log</span> (<span class="st">"Création d'un nouvel article"</span>);
<span class="kw">this</span>.<span class="fu">set</span>(<span class="st">"publicationDate"</span>,<span class="kw">new</span> <span class="kw">Date</span>());
}
});</code></pre>
<p>Refaites les manipulations précédentes, et là (si vous avez laissez suffisamment de temps entre la création des articles), vous pourrez noter que la date est bien mise à jour :</p>
<p><img src="RSRC/03_04_BB.png" alt="BB" /><br /> <img src="RSRC/03_05_BB.png" alt="BB" /><br /></p>
<blockquote>
<blockquote>
<p><strong>Remarque</strong> : la propriété date n’existe plus dans les valeurs par défaut, elle est créée à l’instanciation du modèle lors de l’appel de <code>this.set("publicationDate",new Date())</code> dans la méthode <code>initialize</code>. De la même manière, vous pouvez créer à la volée des propriétés “à posteriori” pour les instances des modèles.</p>
</blockquote>
</blockquote>
<p><strong>Et voilà, l’initiation est terminée. Nous allons pouvoir passer “aux choses sérieuses” et découvrir jusqu’où nous pouvons “pousser” Backbone.</strong></p>
<h2 id="code-final-de-lexemple"><a href="#TOC"><span class="header-section-number">4.6</span> Code final de l'exemple</a></h2>
<p>Le code final de votre page devrait ressembler à ceci :</p>
<pre class="sourceCode html"><code class="sourceCode html"> <span class="dt"><!DOCTYPE </span>html<span class="dt">></span>
<span class="kw"><html></span>
<span class="kw"><head></span>
<span class="kw"><meta</span><span class="ot"> http-equiv=</span><span class="st">"Content-Type"</span><span class="ot"> content=</span><span class="st">"text/html; charset=utf-8"</span><span class="kw">></span>
<span class="kw"><title></span>Backbone<span class="kw"></title></span>
<span class="kw"><link</span><span class="ot"> href=</span><span class="st">"libs/vendors/bootstrap/css/bootstrap.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="kw">></span>
<span class="kw"><style></span>
body <span class="kw">{</span>
<span class="kw">padding-top:</span> <span class="dt">60px</span><span class="kw">;</span>
<span class="kw">padding-bottom:</span> <span class="dt">40px</span><span class="kw">;</span>
<span class="kw">}</span>
<span class="kw"></style></span>
<span class="kw"><link</span><span class="ot"> href=</span><span class="st">"libs/vendors/bootstrap/css/bootstrap-responsive.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="kw">></span>
<span class="kw"></head></span>
<span class="kw"><body></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"navbar navbar-fixed-top"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"navbar-inner"</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"container"</span><span class="kw">></span>
<span class="kw"><a</span><span class="ot"> class=</span><span class="st">"brand"</span><span class="kw">></span>Mon Blog<span class="kw"></a></span>
<span class="kw"></div></span>
<span class="kw"></div></span>
<span class="kw"></div></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"container"</span><span class="kw">></span>