forked from kauemurakami/getx_pattern
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
1177 lines (1098 loc) · 81.1 KB
/
index.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>
<html lang="en">
<head>
<!------preview image link -->
<meta property="og:url" content="https://kauemurakami.github.io/getx_pattern/" >
<meta property="og:title" content="getx_pattern" />
<meta property="og:image" content="images/rocket2.jpg">
<meta property="og:description" content="getx_pattern, faça seus projetos decolarem" >
<meta property="og:image:type" content="image/jpg">
<meta property="og:image:width" content="300">
<meta property="og:image:height" content="300">
<!------wpp fb image -->
<meta property="og:site_name" content="getx_pattern">
<meta property="og:type" content="website" />
<meta charset="UTF-8"/>
<title>getx_pattern</title>
<meta name="description" content="Design pattern pensado em você, que utiliza o package GetX">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="styles.css">
<script src="https://kit.fontawesome.com/b99e675b6e.js"></script>
<link href="https://cdn.rawgit.com/Killercodes/281792c423a4fe5544d9a8d36a4430f2/raw/36c2eb3e0c44133880485a143717bda9d180f2c1/GistDarkCode.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="wrapper">
<div class="sidebar">
<div class="center-text"><i class="fas fa-rocket fa-3x ttpage icon"></i>
</div>
<h2 class="ttpage">getx_pattern</h2>
<ul>
<li><a href="#home"><i class="fas fa-home"></i>Home</a></li>
<li><a href="#estrutura"><i class="fas fa-project-diagram"></i>Estrutura</a></li>
<li><a href="#getx"><i class="fab fa-xing"></i> GetX</a></li>
<li><a href="#data"><i class="fas fa-sitemap"></i>Data</a></li>
<li><a href="#provider"><i class="fas fa-database"></i>Provider</a></li>
<li><a href="#model"><i class="fas fa-copy"></i>Model</a></li>
<li><a href="#repository"><i class="fas fa-archive"></i></i>Repository</a></li>
<li><a href="#controller"><i class="fas fa-gamepad"></i>Controller</a></li>
<li><a href="#bindings"><i class="fab fa-earlybirds"></i> Bindings</a></li>
<li><a href="#ui"><i class="fas fa-mobile-alt"></i>UI</a></li>
<li><a href="#routes"><i class="fas fa-road"></i>Routes</a></li>
<li><a href="#translations"><i class="fas fa-globe-americas"></i>Translations</a></li>
<li><a href="#tutorials"><i class="fab fa-leanpub"></i></i> Tutorials</a></li>
<li>
<a href="#posts">
<pre>
- Posts
</pre>
</a>
</li>
<li>
<a href="#posts">
<pre>
- future site/app
</pre>
</a>
</li>
<li>
<a href="#getx_patter_web_app">
<pre>
- Weather
</pre>
</a>
</li>
<li>
<a href="#login-firebase">
<pre>
- Login Firebase
</pre>
</a>
</li>
<li><a href="#info"><i class="fas fa-info-circle"></i></i>Informações</a></li>
</ul>
<div class="social_media">
<a href="https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets" title="GetX Snippets VSCode Extension" target="_blank">
<i class="fas fa-laptop-code" style=" color:#A901DB;"></i>
</a>
<a href="https://twitter.com/kauemurakami" title="Quick questions? Developer Twitter" target="_blank">
<i class="fab fa-twitter" style=" color:#A901DB;"></i>
</a>
<a href="https://github.com/kauemurakami/getx_pattern" title="GitHub repository" target="_blank">
<i class="fab fa-github" style=" color:#A901DB;"></i>
</a>
</div>
</div>
<div class="main_content">
<div class="info">
<section id="home">
<div><h2><span class="subtitle">getx_pattern</span></h2>uma proposta pra você que utiliza o
<a href="https://pub.dev/packages/get" class="mark" target="_blank">GetX</a>
</div>
<div>
<div class="obs">
Estamos trabalhando em um novo site para você ! <i class="fas fa-hard-hat" style="color: coral;"></i>
</div>
Projeto desenvolvido para padronizar os seus projetos com <a href="https://pub.dev/packages/get" target="_blank" class="mark">GetX</a>.<br><br>
<span class="subtitle"><h2>Objetivos</h2></span>
O objetivo principal, é tornar sua programação com <font color="#BE81F7">Flutter</font> + <a href="https://pub.dev/packages/get" class="mark" target="_blank">GetX</a>
mais agradável e intuitiva do que já é<span class="mark">!</span><br>
Quando há um padrão de desenvolvimento a ser seguido, tudo fica mais fácil para quem usa. <span class="mark">Mas por quê?</span><br><br>
- <span class="mark">Porque</span> assim, podemos nos comunicar de forma "universal" com pessoas que também seguem esses mesmos padrões.<br><br>
- <span class="mark">Há</span> infinitas maneiras de resolver o mesmo problema, então os patterns tem um papel muito importante nisso,
os mesmos problemas, ainda poderão ser resolvidos de várias maneiras, mas com um determinado fluxo a ser seguido.<br><br>
- <span class="mark">Com</span> isso é muito mais fácil sanar suas dúvidas, quando vocês conversam no mesmo padrão.<br><br>
- <span class="mark">Seu</span> projeto não ficará dependente de quem o construiu, pois outros programadores poderão ler e alterar o código sem dificuldades.<br><br>
- <span class="mark">Você</span> terá um melhor aproveitamento na reutilização do seu código, podendo assim reutilizar diversos widgets de outros projetos
por exemplo, que ele se encaixará perfeitamente no seu projeto.<br><br>
- <span class="mark">Que</span> você possa aplicar o uso do <a href="https://pub.dev/packages/get" target="_blank">GetX</a> em projetos profissionais,
tendo uma documentação em mãos, com isso, mais segurança para quem programa, seja você uma empresa ou um estudante em busca de conhecimento.<br>
<div class="obs">
<span class="mark">E</span> além do <span class="mark">getx_pattern</span>, também disponibilizamos uma extensão que irá acelerar muito mais ainda esse processo,
o <a href="https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets" target="_blank">GetX Snippets</a>
tem snippets que irão acelerar seu desenvolvimento, podendo criar desde variáveis a classes inteiras e já está disponível para
o <span class="mark">vscode, Experimente !</span><br>
</div>
Agora que você entendeu nossos objetivos, vamos aprender um pouco sobre a <span class="mark">estrutura</span> do <span class="mark">getx_pattern</span> !<br>
Se você quiser acelerar seu processo de desenvolvimento, recomendamos que conheça nossa extensão para vscode
<a href="https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets" target="_blank">GetX Snippets</a>
</div>
</section>
<section id="estrutura">
<div><h2><span class="subtitle">Estrutura</span></h2></div>
Você pode ficar a vontade para usar a estrutura que desejar em módulos ou em packages. O exemplo inicial lhe oferecerá as mesmas abas para que você
possa acompanhar a construção do projeto de ambas as formas com o mesmo código, então vamos começar! <i class="fas fa-play mark"></i>
<br><br>
<div>
<div class="tab">
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openCity('strc-package')">Estrutura em Packages</button>
<button class="w3-bar-item w3-button" onclick="openCity('strc-modular')">Estrutura em Módulos</button>
</div>
<div id="strc-package" class="w3-container w3-display-container city">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<img src="images/strc.png" alt="The Structure for GetX developers xD" width="500" height="600" class="center">
</div>
<div id="strc-modular" class="w3-container w3-display-container city" style="display:none">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<img src="images/strc_module.png" alt="The Structure for GetX developers xD" width="700" height="600" class="center">
</div>
</div>
<br>
Agora que você conhece a <span class="mark">proposta</span> e deu uma boa analisada na apresentação da estrutura, vamos parar um pouco para falar rapidamente sobre ela,
antes de introduzir você na seção do <span class="mark">GetX</span>, para que você possa seguir nossos exemplos sem dificuldade
ou dúvidas sobre nossos padrões de nomenclatura ou fluxo, pois bem, vamos falar <span class="mark">rapidamente de um por um</span> agora, <span class="mark">não se preocupe</span> se você está
se aventurando e não conhece alguns dos <span class="mark">conceitos</span> que serão abordados aqui, isso é apenas uma apresentação formal com a estrutura,
iremos falar mais <span class="mark">detalhadamente sobre cada uma delas</span>, com exemplos, em suas respectivas seções.<br><br>
<i class="fas fa-copy alpha"></i> <span class="mark topics">Model</span>: É o diretório que irá agrupar todas as nossas classes modelos para nossos objetos.<br>
<div class="obs">Sinta-se a vontade para escolher entre <span class="mark">Model</span> ou <span class="mark">Class</span>, mas tenha em mente que daqui em diante, usarei o termo
Model, caso não seja novidade, garanto que logo irá se acostumar com <span class="mark">Model.</span>
</div>
<i class="fas fa-database alpha"></i> <span class="mark topics">Providers</span>: É o diretório responsável por agrupar nossos <span class="mark">provedores de dados</span>,
pode ser tanto um <span class="mark">banco de dados</span> ou uma <span class="mark">API</span>.<br><br>
<i class="fas fa-archive alpha"></i> <span class="mark topics">Repository</span>: É um ponto <span class="mark">único</span> de acesso aos dados, irá abstrair nossas
<span class="mark">entidades</span>.<br><br>
<i class="fas fa-sitemap alpha"></i> <span class="mark topics">Data</span>: É apenas um diretório responsável por guardar <span class="mark">TUDO</span>
relacionado aos seus dados, ou seja, seu <span class="mark">repository</span>, suas <span class="mark">classes</span> e <span class="mark">providers</span>.
<br><br>
<i class="fas fa-gamepad alpha"></i> <span class="mark topics">Controller</span>: Nossos controllers, nada mais são, que os responsáveis pelas nossas
<span class="mark">regras de negócio</span>, <span class="mark">alterações de estado</span>, também é onde criaremos
<span class="mark">nossos observáveis</span> com seus respectivos <span class="mark">estados iniciais</span> e
os <span class="mark">eventos</span> que serão responsáveis por <span class="mark">alterar esses estados</span>.
<br><br>
<i class="fas fa-mobile alpha"></i> <span class="mark topics">UI</span>: É tudo que o usuário vê, seus widgets, animações, textos, temas.
<br><br>
<i class="fas fa-road alpha"></i> <span class="mark topics">Routes</span>: É o diretório responsável por conter o/os nossos arquivos que são resposáveis por gerênciar nossas rotas.
<br>
<i class="fas fa-road alpha"></i> <span class="mark topics">Bindings</span>: A classe Binding é uma classe que desacopla a injeção
de dependência, enquanto a "ligação" roteia para o gerente de estado e o gerente de dependência. Isso permite conhecer qual
tela está sendo exibida quando um controlador específico é usado e saber onde e como descartá-lo. Além disso, a classe
Binding permitirá que você tenha o controle de configuração do SmartManager. Você pode configurar as dependências a serem
organizadas ao remover uma rota da pilha, ou quando o widget que a utilizou for disposto, ou nenhuma delas. <br>
<br>
<div class="obs">
CASO VOCÊ OPTE PELA OPÇÃO DE ESTRUTURAÇÃO EM MÓDULOS, NOSSA PAGE, CONTROLLER DEVEM SER CONTIDOS DENTRO DE
SEUS RESPECTIVOS MÓDULOS.<br>
CASO VOCÊ ESTEJA USANDO BINDINGS PARA INJETAR DEPÊNDENCIAS, OS MESMOS PERTECEM APENAS A SEU MÓDULO.<BR>
<BR>
A ESTRUTURA EM MÓDULOS É RECOMENDADA PARA PROJETOS MUITO GRANDES, DEIXANDO TUDO RELACIONADO AQUELA VIEW, DISPONÍVEL
DE FORMA FÁCIL.
</div>
<br>
Agora vamos conhecer um pouco mais o <span class="mark">Get</span>, o gerenciador de estados
mais <span class="mark">rápido</span> e <span class="mark">leve</span> !
</div>
</section>
<section id="getx">
<div><h2><span class="subtitle">GetX, seu gerenciador de estado reativo.</span></h2></div>
<div><div class="obs">Primeiramente, é aconselhável que você tenha um conhecimento prévio de <span class="mark">flutter</span> e também uma base
de conhecimento em <span class="mark">gerenciamento de estados</span>, caso não tenha, recomendo uma breve leitura na
<span class="mark">documentação oficial</span> do <span class="mark">flutter</span>
sobre este assunto, para acessar click <a href="https://flutter.dev/docs/development/data-and-backend/state-mgmt/intro" target="_blank">aqui</a>.<br></div>
O foco do <span class="mark">GetX</span> é ter <span class="mark">maior desempenho</span> com o <span class="mark">mínimo consumo de recursos</span>, veja os
<a href="https://github.com/jonataslaw/benchmarks" target="_blank"> benchmarks</a>.<br>
<span class="mark">Produtividade</span>, usando uma sintaxe <span class="mark">fácil</span> e <span class="mark">agradável</span>.<br>
<span class="mark">Organização</span>, permitindo a <span class="mark">dissociação total</span> da sua camada de
<span class="mark">apresentação</span> da sua <span class="mark">regra de negócio</span>.<br>
O <span class="mark">Getx</span> tem o poder de reconstruir apenas o widget quando há uma alteração de estado em uma variável
<span class="mark">.obs</span> em seu controlador. Isso, porque <span class="mark">tudo nele é fluxo</span>, isso nos permite
ouvir o evento de cada 'variável'.<br>
Vamos para um primeiro exemplo da aplicação do <span class="mark">GetX</span> com <span class="mark">o getx_pattern</span>
, do bom e velho contador.<br><br>
Vamos utilizar, neste exemplo, apenas a classe main, para você se familiarizar com os conceitos do
<span class="mark">GetX</span>.<br>
Apague todo conteúdo da sua main.dart e mantenha, ou copie e cole, apenas este trecho de código:
<script src="https://gist.github.com/kauemurakami/fdbc297925a693e1840b5a255c8744dc.js"></script>
Após isso, vamos criar nossa classe controller, que nos permite criar nossa regra de negócio e controlar nossos estados.<br>
Abaixo do código acima cole o seguinte código:
<script src="https://gist.github.com/kauemurakami/0b2e62e0cedb0bfdbcbe0836f84cbc11.js"></script>
O <span class="mark">GetxController</span> é o responsável por nos fornecer os métodos necessários para controlar nossos
observáveis (<span class="mark">.obs</span>), permitindo atualizar nossos widgets GetX, respondendo às mudanças de
estados da nossa aplicação.
No exemplo acima declaramos uma variável e dois métodos, vamos falar sobre eles.<br><br>
Com <span class="mark">GetX</span>, podemos extender a classe <span class="mark">GetxController</span>, e com ele, podemos
criar varáveis observáveis adicionando um simples <span class="mark">.obs</span> e <span class="mark">seu estado inicial</span>.<br>
<span class="mark"> final [var] = [initial-value].obs;</span> <br>
Nosso observável só pode ser <span>final</span>, e seu tipo será atribuido a partir do <span class="mark">initial-value</span>
inserido no momento da declaração, por ser <span>final</span>, o mesmo só pode ser inserido uma vez.<br><br>
<span class="mark">Mas e agora?</span> Se final só pode ser modificada uma vez, como vou alterar o valor dessa variável?<br>
A resposta é tão simples quanto curta, <span class="mark">.value</span>. Ao criar sua variável como um observável, ela irá criar,
por trás do capô, um RxObject,exemplo, um tipo int <i class="fas fa-chevron-right mark"></i> Rxint, um tipo List< User>() <i class="fas fa-chevron-right mark"></i>
RxList< User>(), e seu valor e tipo original é guardado no seu atributo <span>value</span> desse RxObject.<br>
No caso das nossas <span class="mark">Listas</span>, não é necessário utilizar o <span class="mark">.value</span>,
então diferente de um <span class="mark">RxString</span> onde você acessaria o valor contido com <span class="mark">text.value</span>, com as listas você pode trabalhar normalmente, tendo
em vista que tanto sua lista, como os objetos dentro dela, são todos observáveis, portanto podemos acessar seus atributos dessa maneira
<span class="mark">myList.length</span> ou <span class="mark">myList[index].name</span>.<br><br>
Vamos a classe Stateless, responsável pela visualização do nosso contador. Você não leu errado, com <span class="mark">GetX</span>
você nunca mais irá precisará um <span class="mark">stateful</span> quando quiser alterar seus estados, <span class="mark">esqueça o setState</span>,
nosso widget <span>GetX</span> é reconstruído sempre que um objeto, nele contido, tenha o estado alterado pelo
<span class="mark">controller</span> setado no widget.<br>
Vamos ao código:<br>
<script src="https://gist.github.com/kauemurakami/7788d19e7dc98769f316c4021eca2635.js"></script>
Bem, isso é um widget básico, estamos apenas mostrando um text e dois botões responsáveis por acionar os nossos eventos
<span class="mark">decrement()</span> e <span class="mark" >increment()</span>, lembra? Estão no nosso controller<i class="fas fa-gamepad"></i>.<br>
Repare um pouco melhor, a primeira coisa que deve ter notado é que estamos utilizando <span class="mark">3 GetX</span>
widgets, <span class="mark">mas porquê</span>?<br>
Bem, isso deve ser abordado primeiro para que você possa entender como aplicar melhor este widget, e não usá-lo de forma,não errada,
mas desnecessária, pois bem, primeiro temos um <span>GetX</span> widget do tipo <span class="mark">MyController</span>,
onde nossa lógica se encontra.<br><br>
Mas o que ele tem diferente dos outros? Bem, a propriedade <span class="mark">init</span>, ela é responsável por criar nossa instância do
objeto <span>controller</span> e dispinibiliza-lo na função builder desde widget, você já deve ter percebido, mas é isso mesmo,
nosso <span class="mark">controlador</span> corresponde ao nosso <span class="mark">_</span> (underline), com isso você pode acessar seus
observáveis apenas usando a instância do seu controlador, dessa forma <span class="mark">_.num</span>.<br>
Agora que temos nosso primeiro widget <span class="mark">GetX</span> com controlador inicializado, não precisamos inicializa-lo novamente,
apenas setar o tipo no dele, caso estejam na mesma classe/page, dessa forma <span class="mark"> Getx<[type]></span>, e ele se encarregará do resto para você, fácil não? E
você pode ficar tranquilo, sem boilerplate, o <span class="mark">GetX</span> é sensacional, e ainda sabe a hora certa de remover esse
controlador da memória. Você também pode controlar isso se quiser, com <span class="mark">GetX</span> é assim, ele deixa você livre
para focar na qualidade do seu código, sem se preocupar com questões repetitivas e fáceis de lidar como essa, ele cuida de tudo pra você.
<br>
Mas e o <span class="mark">.value</span>?<br>
Bem, é aí que entra uma das propostas do <span class="mark">getx_pattern</span>, nós achamos melhor manter tudo que for controlado
na interface dentro do controlador, isso inclui os estados de suas variáveis e os eventos que levarão a isso, assim como nosso exemplo
temos a variável num, que é declarado no controller e a mesma, é usada no Getx widget, e nossas funções/eventos, responsáveis por
alterar o estado dessa nossa variável. Portanto, carregar <span class="mark">_.num.value</span> vai contra as boas práticas, preferimos
que o controlador seja responsável até por isso, criando um <span class="mark">get</span> e um <span class="mark">set</span> para que
possamos abstrair o <span class="mark">.value</span> do código da sua vizualização, deixando seu código mais legível e sem <span class="mark">boilerplate</span>.<br><br>
<br>Além do widget observável <span class="mark">GetX< Controller >()</span>, o GetX Também possui o <span class="mark">Obx(() => Widget())</span>,
sendo este, responsável por reconstruir nossos widgets <span class="mark">considerados pesados</span>.<br>
E o que o <span class="mark">GetX</span> entende por widget leve e pesado?<br>
Vamos falar um pouco sobre isso.<br>
O widget <span class="mark">Text(_.count)</span> do nosso exemplo é um widget 'leve', pois estamos o alterando <span class="mark">DIRETAMENTE</span>
Isso quer dizer: <br><br>
<div class="obs">
GetX< MyController>(builder: (_) => Text(_.var))<br>
Uma observação importante neste ponto é que <span class="mark">Containers</span> não são considerados
<span class="mark"> filhos diretos.</span><br>
Dessa forma o exemplo a seguir também é valido para o uso do <span class="mark">GetX</span>
<br>GetX< MyController>(builder: (_) => Container(child: Text(_.var)))<br><br>
Widgets são considerados pesados quando possui uma grande hierarquia de filhos, como uma <span class="mark">lista</span>
ou um <span class="mark">card complexo</span>. Nesses casos, ao tentar usar o <span class="mark">GetX widget</span> para reconstruir esse
list ou card, você receberá um erro de uso indevido.<br>
Para esses casos, você pode fazer o uso do <span class="mark">Obx(() => WidgetPesado())</span>.<br>
Onde <span class="mark">WidgetPesado</span> se subentende uma Lista, que pode possuir Widgets <span class="mark">Getx</span>
para a alteração de cada elemento e o <span class="mark">Obx</span> para atualização da lista completa.<br>
Seu uso se mostra muito eficiente ao ser combinado com <span class="mark">GetView</span>, estendendo sua Page,
juntamente com bindings para ela, você verá isso no exemplo mais sólido desta documentação seções adiante.<br>
Mas basicamente você ira ter uma instância do seu <span class="mark">controller</span> ao invés do <span class="mark">_ </span>.<br>
</div>
Isso foi uma breve introdução sobre o uso do<span class="mark">GetX</span>, vamos aplicar isso também em outros instantes, se você não entendeu tudo até
aqui, não se preocupe.<br>
Se quer saber mais sobre o <span class="mark">GetX</span>, visite seu <span class="mark"><a href="https://pub.dev/packages/get" target="_blank">
package no pubdev</span></a>, ou seu repositório no <span class="mark"><a href="https://github.com/jonataslaw/get" target="_blank">GitHub aqui</span></a>.
</div>
</section>
<section id="data">
<div><h2><span class="subtitle">Data</span></h2></div>
<div>Aqui não teremos muito o que discutir, é apenas um repositório onde você irá abstrair/empacotar <span class="mark">TUDO</span>
relacionado aos seus dados, seus <span class="mark"> modelos</span>, seus <span class="mark">repositories</span> e
<span class="mark">provedores</span> de dados. Caso você opte por usar a versão em <span class="mark">módulos</span>,
<span class="mark">Data</span> terá o mesmo papel, deixando seus dados disponíveis para <span class="mark">todos</span>
os seus <span class="mark">módulos</span>, deixando só o que é <span class="mark">vital</span> para seu
<span class="mark">módulo</span> nele!!
<br>
Isso foi pensado para que você possa manter sua estrutura de diretórios o
<span class="mark">menor possível</span> ao trabalhar com flutter, e ao mesmo tempo, ser algo <span class="mark">intuitivo</span> e
<span class="mark">didático</span> para acelerar sua curva de aprendizado.</div>
<div class="obs">
Vamos começar o uso do <span class="mark">pattern</span> aqui, ao avançar das seções você vamos utilizar o <span class="mark">JSONPlaceHolder</span> para exemplificar
o consumo de uma <span class="mark">API</span> com essa estrutura.
</div>
<span class="mark">Vamos lá!!!</span><br> Crie os seguintes repositórios, dentro de <span class="mark">lib</span>.
<div class="tab">
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openCity('data-package')">Em Packages</button>
<button class="w3-bar-item w3-button" onclick="openCity('data-modular')">Em Módulos</button>
</div>
<div id="data-package" class="w3-container w3-display-container city">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
<span class="green">|-- app</span>
<span class="green">|-- data</span>
main.dart
</pre>
</div>
<div id="data-modular" class="w3-container w3-display-container city" style="display:none">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
<span class="green">|-- app</span>
<span class="green">|-- modules</span>
<span class="green">|-- home</span>
<span class="green">|-- data</span>
main.dart
</pre>
</div>
</div>
</section>
<section id="provider">
<div><h2><span class="subtitle">Provider</span></h2></div>
<div class="obs">
Em algumas outras estruturas, o termo <span class="mark">'provider'</span>, pode ser abordado de várias formas, mas aqui, ele existe
<span class="subtitle">única</span> e <span class="subtitle">exclusivamente</span>, para fazer requisições http ou
persistência num banco de dados. <span class="mark">Caso você use os dois</span>, crie os respectivos diretórios
e/ou arquivos <span class="subtitle">dentro</span> deste.<br>
Caso haja <span class="mark">muitas requisições, em um único arquivo</span>, você pode optar por separar por <span class="mark">entidades</span>,
ou manter no mesmo arquivo, isso é uma escolha pessoal e vai de cada programador.<br>
</div>
Vamos começar a <span class="mark">construir</span> nosso exemplo por aqui.<br>
Comece criando um diretório chamado <span class="mark">provider</span>, dentro de <span class="mark">Data</span> que irá conter todos os arquivos que fornecem
dados para nossa aplicação, juntamente com a classe responsável por capturar/enviar nossos dados neste exemplo. Se você quiser
criar essa
classe de forma mais <span class="mark">rápida</span>, use nossa <span class="mark">extensão</span> para vscode.
<a href="https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets" target="_blank">GetX Snippets</a>.<br>
Comece criando um arquivo chamado <span class="mark">api.dart</span>, ou o nome que desejar.
<div class="tab">
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openCity('provider-package')">Em Packages</button>
<button class="w3-bar-item w3-button" onclick="openCity('provider-modular')">Em Módulos</button>
</div>
<div id="provider-package" class="w3-container w3-display-container city">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- data
<span class="green">|-- provider</span>
<span class="green">api.dart</span>
main.dart
</pre>
</div>
<div id="provider-modular" class="w3-container w3-display-container city" style="display:none">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- modules
|-- home
|-- data
<span class="green">|-- provider</span>
<span class="green">api.dart</span>
main.dart
</pre>
</div>
</div>
É dentro deste aquivo que iremos escrever nossa classe, copie o exemplo a seguir, ou se estiver usando nossa
<a href="https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets" target="_blank">extensão</a>
basta começar escrevendo <span class="mark">getprovider</span> e pronto, ela lhe trará uma classe como a do exemplo!!
<script src="https://gist.github.com/kauemurakami/c8514d795de489632f51d162bacd69b9.js"></script>
<div class="obs">Não se preocupe com os erros até o momento, ao decorrer das seções posteriores, vamos criar todas as
dependências.
</div>
Como podem ver, temos uma classe <span class="mark">MyApiClient</span> com um <span class="mark">parâmetro requerido</span>,
nosso objeto <span class="mark">http.Client</span>, que será usado neste exemplo para fazer todas as requisições à <span class="mark">API</span>.<br>
Por fim, temos nosso método <span class="mark">getAll</span> que tem como papel, recuperar todos os <span class="mark">posts</span> da <span class="mark">API</span>.<br>
Iremos adicionar mais métodos futuramente.
</section>
<br>
<section id="model">
<div><h2><span class="subtitle">Model</span></h2></div>
<div>Na nossa classe modelo teremos nossos atributos e dois métodos, <span class="mark">toJson</span> e <span class="mark">fromJson</span>
responsáveis por converter nosso <span class="mark">objeto</span> em <span class="mark">json</span> ou um <span class="mark">json</span> em nosso <span class="mark">objeto</span>.<br>
<div class="obs">
Geralmente quando trabalhamos com API's, usamos esses métodos para criar objetos a partir da resposta da nossa API, ou criar um json para
enviar para nossa API.
</div>
Comece criando o diretório <span class="mark">model</span> e um arquivo <span class="mark">model.dart.</span>
</div>
<div class="tab">
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openCity('model-package')">Em Packages</button>
<button class="w3-bar-item w3-button" onclick="openCity('model-modular')">Em Módulos</button>
</div>
<div id="model-package" class="w3-container w3-display-container city">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- data
|-- provider
api.dart
<span class="green">|-- model</span>
<span class="green">model.dart</span>
main.dart
</pre>
</div>
<div id="model-modular" class="w3-container w3-display-container city" style="display:none">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- modules
|-- home
|-- data
|-- provider
api.dart
<span class="green">|-- model</span>
<span class="green">model.dart</span>
main.dart
</pre>
</div>
</div>
Agora vamos ao código, copie e cole o seguinte código, ou se estiver usando nossa
<a href="https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets" target="_blank">extensão</a>
comece escrevendo <span class="mark">getmodel</span>
<script src="https://gist.github.com/kauemurakami/811f14ee186b7b089b2db7e18e29cb6a.js"></script>
</section>
<section id="repository">
<div><h2><span class="subtitle">Repository</span></h2></div>
<div class="obs">
<span class="mark">É o responsável por separar suas entidades</span>, basicamente, entidades são todas as "tabelas" da sua base
de dados que irão interagir com seu ou seus <span class="mark">providers</span>.<br>
O <span class="mark">repository</span> tem o objetivo de abstrair e separar, sua
<span class="mark">fonte de dados</span> do seus <span class="mark">controladores</span>, tendo assim,
um <span class="mark">ponto único de falha</span>, ou seja, se um dia você vier a trocar a API ou base de
dados do seu projeto, basta alterar seus arquivos <span class="mark">providers</span>,
não sendo necessária nenhuma alteração no <span class="mark">repository</span>, pois ele só é responsável por chamar a função do <span class="mark">provider</span>, não havendo lógica nenhuma ali.<br>
<span class="mark">Ex:</span> Imagine que você possua um aplicativo de venda de produtos, que possua apenas os clientes e os produtos de um estabelecimento.<br>
Podemos identificar facilmente nossas <span class="mark">entidades</span> nos fazendo uma pergunta.<br>
<span class="mark">Irei receber e/ou enviar dados dessa entidade? </span>Se a resposta for sim, então ela precisa de um repository.<br>
No nosso exemplo teríamos três <span class="mark">repositories,</span> UserRepository, ProdutoRepository, EstabelecimentoRepository.<br>
Algumas vezes, podemos tirar essas entidades nos baseando em nossas classes, mas muitas vezes existem classes auxiliares que não estão
necessariamente na sua base de dados ou API, portanto preferimos nos basear no que realmente interage com sua base de dados.
</div>
Dessa forma, tiramos muita responsabilidade do nosso <span class="mark">controller</span>, ele não precisa saber de onde vem os dados,
apenas consumi-los, outra vantagem é que o repository faz a nossa ligação Controller <span class="mark"><-> </span>Dados.<br>
Tendo assim, uma melhor <span class="mark">organização</span>, deixando o código <span class="mark">compreensivo</span> e é extremamente fácil a manutenção, de forma <span class="mark">intuitiva</span>.<br>
No nosso exemplo, nosso <san class="mark">repository</san> será responsável pelo meio de campo entre a <span class="mark">api</span> e o <span class="mark">controller</span>,
sendo o responsável pela chamada da API no controller.<br><br>
Vamos então criar o nosso diretório <span class="mark">repository</span> e um arquivo <span class="mark">posts_repository.dart</span>
<div class="tab">
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openCity('repository-package')">Em Packages</button>
<button class="w3-bar-item w3-button" onclick="openCity('repository-modular')">Em Módulos</button>
</div>
<div id="repository-package" class="w3-container w3-display-container city">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- data
|-- provider
api.dart
|-- model
model.dart
<span class="green">|-- repository</span>
<span class="green">posts_repository.dart</span>
main.dart
</pre>
</div>
<div id="repository-modular" class="w3-container w3-display-container city" style="display:none">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- modules
|-- home
|-- data
|-- provider
api.dart
|-- model
model.dart
<span class="green">|-- repository</span>
<span class="green">posts_repository.dart</span>
main.dart
</pre>
</div>
</div>
Vejamos o exemplo, copie e cole o código a seguir, ou se possuir nossa
<a href="https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets" target="_blank">extensão</a>
basta apenas começar a escrever <span class="mark">getrepository</span>
<script src="https://gist.github.com/kauemurakami/cd8b0e4b5741f9cd77cb0015843d4f58.js"></script>
Com isso, finalizamos a parte do nosso projeto que cuida dos dados da nossa aplicação, vamos consumi-los agora !
</section>
<section id="controller">
<div><h2><span class="subtitle">Controller</span></h2></div>
<div class="obs">
Os controladores são a parte vital da sua aplicação, neles você irá criar suas variáveis <span class="mark">.obs</span>
que guardará valores que podem ser alterados durante a aplicação.<br>
Seu controlador é responsável também por <span class="mark">consumir seus dados</span>>, através dos seus
<span class="mark">repositórios</span>, que por sua vez, só realizam as chamadas dos dados dos seus <span class="mark">providers</span><br>
<span class="mark">Regra</span>: Todo controller deve possuir <span class="mark">um, e apenas um, repository</span>, sendo esse,
um atributo <span class="mark">requerido</span> para inicializar seu controller no seu <span class="mark">GetX</span> widget.<br>
Caso você venha a precisar de dados de dois repositories diferentes em uma mesma page, você deve usar dois <span class="mark">GetX</span> widgets.
Recomendamos que haja, no mínimo, <span class="mark">um controller para cada page</span>.<br>
Só existe uma exceção para que você possa usar o mesmo controlador para varias pages, e é bem simples:<br><br>
<span class="mark">IMPORTANTE</span> <br>
Você poderá usar <span class="mark">um controlador</span> em <span class="mark">várias páginas</span>,
<span class="mark">única e exclusivamente</span>, se os dados de <span class="mark">todas as pages</span>,
<span class="mark">consumirem um único repositório</span>.<br><br>
O objetivo disso é fazer com que você use o <span class="mark">GetX</span> e aproveite todo seu poder, assim sempre que precisar manipular
duas entidades, você precisará de dois controladores diferentes e uma view.<br>
<span class="mark">Por que?</span> Imagine que você possua um <span class="mark">controller</span>
com <span class="mark">dois repositórios</span>, e esse controller está sendo usado com um <span class="mark">GetX</span> widget
em uma <span class="mark">page</span>, utilizando dados recuperados pelo controller dos dois repositórios.<br>
Sempre que uma entidade for modificada, o controlador irá atualizar seus widgets responsáveis pelas <span class="mark">duas variáveis</span>, sendo que uma delas
<span class="mark">não necessitava alteração</span>. Portanto, separar <span class="mark">um repositório</span> por
<span class="mark">controlador</span>, pode ser uma boa prática ao se trabalhar com o <span class="mark">GetX</span> widget,
tendo um <span class="mark">controlador</span> responsável para <span class="mark">cada widget</span>, que de alguma forma, mostra
essas informações apartir deles, renderizando apenas o widget que teve sua variável <span class="mark">.obs</span> alterada.<br><br>
</div>
Então vamos criar nosso diretório <span class="mark">controller</span> e um arquivo <span class="mark">controller.dart</span>
<div class="tab">
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openCity('controller-package')">Em Packages</button>
<button class="w3-bar-item w3-button" onclick="openCity('controller-modular')">Em Módulos</button>
</div>
<div id="controller-package" class="w3-container w3-display-container city">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- data
|-- provider
api.dart
|-- model
model.dart
|-- repository
posts_repository.dart
<span class="green">|-- controller</span>
<span class="green">|-- home_controller</span>
<span class="green">home_controller.dart</span>
main.dart
</pre>
</div>
<div id="controller-modular" class="w3-container w3-display-container city" style="display:none">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app</span>
|-- modules</span>
|-- home</span>
<span class="green">home_controller.dart</span>
|-- data</span>
|-- provider
api.dart
|-- model</span>
model.dart</span>
|-- repository
posts_repository.dart
<span class="green">app_controller.dart</span>
main.dart
</pre>
</div>
</div>
Vamos ao código do nosso exemplo, copie e cole o código abaixo, ou se estiver usando nossa
<a href="https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets" target="_blank">extensão</a>
basta começar escrevendo <span class="mark">getcontroller</span> e pronto !
<script src="https://gist.github.com/kauemurakami/52aa73bf804b9773b3305d0e01370ccb.js"></script>
Vamos falar um pouco sobre o que temos no <span class="mark">controller</span> até o momento.<br>
<br>
Primeiramente podemos ver nosso repositório como um <span class="mark">@required</span>, pois vamos utilizar nosso
<span class="mark">repository</span> para recuperar nossos dados, <span class="mark">reparem que não preciso saber de
onde vem esses dados</span>, eu apenas preciso me preocupar em consumir o meu <span class="mark">repository</span>.<br>
<br>
Logo em seguida, vemos nossa variável <span class="mark">postsList</span> que é um <span class="mark">.obs</span>, responsável pela
nossa <span class="mark">lista de posts</span>, a mesma que iremos exibir na nossa <span class="mark">page</span> na próxima seção.<br><br>
Reparem que ela foi criada como <span class="mark">privado</span>, por isso criamos nossos
<span class="mark">get</span> and <span class="mark">set</span>. Como foi abordado antes, gostamos de deixar toda responsabilidade de
alteração de estados dentro do controller, portanto ao atribuir algum valor a essa variável, isto será feito dentro do controller, sem
necessidade de usar o <span class="mark">.value</span>, o mesmo já está presente no seu <span class="mark">controller</span>.<br><br>
Por último temos a funçao <span class="mark">getAll</span> do nosso <span class="mark">controlador</span>, reparem também,
que usamos o mesmo nome para a função independente da classe que ela se encontrava, isso facilita na localização independente do arquivo,
ao ver essa função no <span class="mark">controller</span> você poderia ir direto para seu <span class="mark">provider</span>,
sem precisar procurar no seu <span class="mark">repository</span>, caso você usasse um nome diferente.<br>
Você deve ter percebido até aqui que não usamos o <span class="mark">Future</span>, ao invés disso, usamos o <span class="mark">.then</span>
<div class="obs">
Essa função aguarda o retorno de uma função e atribui a data, com isso você não precisa mais usar FutureBuilders nunca mais!!<br>
Basta chamar a função com <span class="mark">funcao().then</span> atribuir o retorno ao seu <span class="mark">.obs</span> e
consumir com um<span class="mark">GetX widget</span>.<br>
Com isso podemos aguardar na nossa <span class="mark">page</span> até que a lista seja preenchida com um <span class="mark">
loading</span> por exemplo, você verá isso melhor na próxima seção.
</div>
Agora vamos criar um controller simples, apenas recebendo o post selecionado na lista <span class="mark"> home</span>.<br>
Para isso, vamos usar um recurso muito simples e interessante do <span class="mark">Getx</span>, <span class ="mark">arguments</span>
você pode passar ele assim que você chama uma rota, e pode receber o valor em uma variável quando o controlador for inicializado.
<script src="https://gist.github.com/kauemurakami/ceec34786ccb2af7f48a276716e24441.js"></script>
</section>
<section id="bindings">
<div><h2><span class="subtitle">Bindings</span></h2></div>
Ideal para seu <span class="mark">gerenciamento de dependências</span>, os bindings podem inicializar seus controladores e
repositórios, API's e o que você precisar, sem a necessidade de chama-los diretamente na View!<br>
No nosso exemplo iremos inicializar dois controladores, juntamente com seus respectivos repositórios,
criando um <span class="mark">binding inicial no seu arquivo main</span> para nossa home e
outro através da <span class="mark">rota</span> em que iremos acessar nossa DetailsPage.<br>
Vamos criar os bindings e depois falar um pouco sobre eles.
<div class="tab">
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openCity('bindings-package')">Em Packages</button>
<button class="w3-bar-item w3-button" onclick="openCity('bindings-modular')">Em Módulos</button>
</div>
<div id="bindings-package" class="w3-container w3-display-container city">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
<span class="green">|-- bindings</span>
<span class="green">my_binding.dart</span>
|-- data
|-- provider
api.dart
|-- model
model.dart
|-- repository
posts_repository.dart
|-- controller</span>
|-- home_controller</span>
home_controller.dart</span>
main.dart
</pre>
</div>
<div id="bindings-modular" class="w3-container w3-display-container city" style="display:none">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app</span>
|-- modules</span>
|-- home</span>
<span class="green">home_binding.dart</span>
home_controller.dart</span>
|-- data</span>
|-- provider
api.dart
|-- model</span>
model.dart</span>
|-- repository
posts_repository.dart
app_controller.dart</span>
main.dart
</pre>
</div>
</div>
Com nosso diretório bindings criado, ou em seus respectivos módulos, crie dois arquivos, <span class="mark">home_bindings.dart e details_binding.dart</span>.<br>
Repare que você pode fazer isso para todas as suas views, desde que siga a orientação de usar <span class="mark">sempre</span>
um <span class="mark">controlador</span> para cada <span class="mark">page</span>.<br>
Vamos aos arquivos.
<script src="https://gist.github.com/kauemurakami/06d1aca39cad574355e3d44d3a81875c.js"></script>
<script src="https://gist.github.com/kauemurakami/2ac66a205565ee35b9cadd0eae4c6d2c.js"></script>
Pronto ! Agora podemos ir para a próxima seção fazer o uso dos nossos bindings !
</section>
<section id="ui">
<div><h2><span class="subtitle">UI</span></h2></div>
Aqui vamos agrupar <span class="mark">tudo</span> relacionado a nossa interface do usuário.
<div class="obs">
Também temos uma proposta de como você deve agrupar esses elementos internamente.<br>
Uma das maiores <span class="marl">vantagens</span> do flutter é o modo como fica fácil "<span class="mark">componentizar</span>" sua<span class="mark"> UI</span>, portanto neste diretório
você deve criar <span class="mark">um diretório para cada page</span>, neste diretório, além da sua <span class="mark">page</span>,
podemos adicionar um outro diretório, de <span class="mark">widgets para cada page</span>, dessa forma sua
page principal pode ser <span class="mark">lida facilmente</span>, pois é montada com <span class="mark">vários widgets</span>.<br>
E se você já adivinhou, podemos fazer isso também no nível da <span class="mark">UI</span>, criando um diretório de <span class="mark">widgets globais</span>,
que virão a ser utilizados em <span class="mark">mais de uma page</span> na sua aplicação.<br>
Caso você não precise usar widgets em determinada page, basta ignorar essa orientação, mas <span class="mark">sempre que for criar uma page</span>, preferimos
que você <span class="mark">crie um diretório para ela</span>, pois <span class="mark">futuramente</span> pode vir a ter widgets externos a ela,
dessa maneira você não irá perder tempo resolvendo erros de importação.
</div>
Vamos entender melhor adicionando seu diretório a estrutura.
<div class="tab">
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openCity('ui-package')">Em Packages</button>
<button class="w3-bar-item w3-button" onclick="openCity('ui-modular')">Em Módulos</button>
</div>
<div id="ui-package" class="w3-container w3-display-container city">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- data
|-- provider
api.dart
|-- model
model.dart
|-- repository
posts_repository.dart
|-- controller
|-- home_controller
home_controller.dart
<span class="green">|-- ui</span>
<span class="green">|-- android</span>
<span class="green">|-- widgets</span>
<span class="green">my_reusable_global_widget.dart</span>
<span class="green">|-- home</span>
<span class="green">|-- widgets</span>
<span class="green">my_reusable_home_widget.dart</span>
<span class="green">home_page.dart</span>
<span class="green">|-- ios</span>
<span class="green">|-- theme</span>
<span class="green">my_theme.dart</span>
main.dart
</pre>
</div>
<div id="ui-modular" class="w3-container w3-display-container city" style="display:none">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- modules
<span class="green">|-- widgets</span>
<span class="green">my_reusable_global_widget.dart</span>
|-- home
<span class="green">|-- widgets</span>
<span class="green">my_reusable_local_widget.dart</span>
home_controller.dart
<span class="green">home_page.dart</span>
|-- data
|-- provider
api.dart
|-- model
model.dart
|-- repository
posts_repository.dart
<span class="green">|-- theme</span>
<span class="green">my_theme.dart</span>
<span class="green">app_controller.dart</span>
<span class="green">app_widget.dart</span>
main.dart
</pre>
</div>
</div>
Agora vamos ao nosso exemplo, copie e cole o código abaixo, ou se estiver usando nossa
<a href="https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets" target="_blank">extensão</a>
basta começar escrevendo <span class="mark">getpage</span> e pronto !
<script src="https://gist.github.com/kauemurakami/f84e9f4fb522e886c6f0102a536dddf6.js"></script>
Vamos falar um pouco sobre o que está acontecendo em nossa <span class="mark">page</span>.<br>
Repare que não estamos declarando nosso controller em lugar algum, estamos estendendo uma <span class="mark"></span>
<span class="mark">GetView< HomeController ></span>, em nosso arquivo <span class="mark">main</span>. Nossa
classe <span class="mark">HomeBinding()</span> está sendo injeta na home, sendo ela a página inicial
recebendo nosso <span class="mark">HomeBinding</span>.<br>
Você pode ter acesso ao seu controlador usando <span class="mark">controller.att</span>, normalmente.<br>
Isso deixa nosso código muito mais limpo e legível.<br>
Em nossa função <span class="mark">build</span> temos um <span class="mark">Scaffold</span> simples,
com um <span class="mark">container</span> e um <span class="mark">GetX</span> widget.<br>
Nele, iniciamos nosso <span class="mark">controlador</span>, e no <span class="mark">initState do GetX</span> buscamos
o <span class="mark">controlador </span> e chamamos a função <span class="mark">getAll</span>, responsável por atribuir a nossa
lista de <span class="mark">posts _postsList</span> no nosso <span class="mark">controlador</span><br>
Então verificamos o tamanho da lista e assim que começarmos a receber a lista de <span class="mark">posts</span>
criamos nossa <span class="mark">ListViewBuilder</span> contendo um <span class="mark">ListTile</span>
exibindo o <span class="mark">title</span> e o <span class="mark">body</span> do nosso <span class="mark">objeto</span>
em um determinado <span class="mark">index</span>, lembrando que o <span class="mark">length</span>,
é o <span class="mark">tamanho da nossa lista</span>, mais um motivo para o
<span class="mark">GetX</span> widget estar envolvendo nossa <span class="mark">ListViewBuilder</span>.<br>
<div class="obs">
Lembrando que, como nossa função <span class="mark">getAll</span> é <span class="mark">async</span>, isso quer dizer
que não vai interromper o funcionamento da aplicação, por isso temos um
<span class="mark">CircularProgressIndicator</span> para exibir enquanto não recebemos nossa
<span class="mark">postsList</span> no nosso <span class="mark">controller</span>.
</div>
Estamos <span class="mark">quase prontos</span>, só vamos falar sobre algumas coisas que podem
<span>agradar</span> você, antes de irmos para a seção de <span class="mark">rotas</span> e modificar nossa
<span class="mark">main.dart</span> para você executar o app :<font color="red">)</font><br>
Vamos falar sobre nosso <span class="mark">theme</span>, nele você pode definir temas para as cores do seu app,
ou modificar o tema de alguns botões de maneira fácil, portanto pensamos em demonstrar o uso para que você possa tirar
maior proveito do <font color="#BE81F7">flutter</font>!<br>
Veja um exemplo, usaremos <span class="mark">appTheme</span> em nossa <span class="mark">main.dart</span> mais adiante.<br>
<script src="https://gist.github.com/kauemurakami/1cdf86f7b8de2bdf4e5c948c2142bb2e.js"></script>
Agora vamos às rotas, e logo depois usaremos nosso
<font color="red">T</font><font color="blue">E</font><font color="green">M</font><font color="orange">A</font><br>
</section>
<br>
<section id="routes">
<div><h2><span class="subtitle">Rotas</span></h2></div>
A ideia é que você possa gerenciar suas rotas de forma fácil, limpa e <span class="mark">segura</span>.<br>
Mudamos nossa maneira de manipular suas rotas, a proposta é que você separe suas <span class="mark">rotas</span>
de sua navegação de <span class="mark">pages</span>.<br><br>
<span class="mark">Porque?</span><br>
Para que suas rotas sejam sempre CONSTANTES, dessa maneira você pode navegar dessa maneira com GetX
<span class="mark">Get.toNamed(Routes.ROTA_CONSTANTE)</span>.<br><br>
Tanto <span class="mark">Routes quanto AppPages</span>, serão classes <span class="mark">abstratas</span>, para que você não cometa nenhum engano
instanciando-as por engano, viu nós cuidamos de você.<br>
<br>
Então agora chega de procurar as rotas nas pages, e chega de alterar uma por uma quando necessário alteração, basta alterar
<span class="mark">em um único lugar</span> e seu app continuará funcionando normalmente!!<br>
Crie os diretórios dessa forma
Crie o diretório <span class="mark">routes</span> e o arquivo <span class="mark">my_routes.dart</span> que conterá nossas rotas.
<div class="tab">
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openCity('routes-package')">Em Packages</button>
<button class="w3-bar-item w3-button" onclick="openCity('routes-modular')">Em Módulos</button>
</div>
<div id="routes-package" class="w3-container w3-display-container city">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- data
|-- provider
api.dart
|-- model
model.dart
|-- repository
posts_repository.dart
|-- controller
|-- home_controller
home_controller.dart
|-- ui
|-- android
|-- widgets
my_reusable_global_widget.dart
|-- home
|-- widgets
my_reusable_home_widget.dart
home_page.dart
|-- ios
|-- theme
app_theme.dart
<span class="green">|-- routes</span>
<span class="green">app_routes.dart</span>
<span class="green">app_pages.dart</span>
main.dart
</pre>
</div>
<div id="routes-modular" class="w3-container w3-display-container city" style="display:none">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- modules
|-- home
home_controller.dart
home_page.dart
|-- data
|-- provider
api.dart
|-- model
model.dart
|-- repository
posts_repository.dart
|-- theme
app_theme.dart
<span class="green">|-- routes</span>
<span class="green">app_routes.dart</span>
<span class="green">app_pages.dart</span>
app_controller.dart
app_widget.dart
main.dart
</pre>
</div>
</div>
Vamos a um exemplo, onde definimos apenas nossa rota principal e rota de detalhes.<br>
Copie e cole o código abaixo, ou se estiver usando nossa
<a href="https://marketplace.visualstudio.com/items?itemName=get-snippets.get-snippets" target="_blank">extensão</a>
comece escrevendo <span class="mark">getroutes</span>, isso lhe trará uma
<span class="mark">classe completa</span> com algumas constantes como exemplo </span> de <span class="mark">rotas</span>.
<script src="https://gist.github.com/kauemurakami/75e857ef363d3a52dc320dc21696e81e.js"></script>
Procure saber tudo que você pode fazer com as rotas, como middleware, parâmetros e mais na documentação oficial do
<a href="https://pub.dev/packages/get#navigation-without-named-routes">GetX</a>.
<br>
Agora nosso arquivo de navegação, <span class="mark">Apppages</span>, essa classe conterá um array do tipo
<span class="mark">GetPage</span>, e dentro dela, iremos declarar todas as nossas navegações, usando nossa
<span class="mark"> classe Routes</span> para recuperar os nomes das nossas rotas.<br>
<script src="https://gist.github.com/kauemurakami/b9aae348d67744fede76075c93d8e836.js"></script>
<br>
<section id="translations">
<div><h2><span class="subtitle">Internacionalização</span></h2></div>
Se você deseja fazer aplicativos que irão romper nossas fronteiras, isso não é um problema quando se trabalha com GetX!<br>
Você pode criar chaves para palavras, frases e até mesmo parâmetros dinâmicos são permitidos!<br>
E para usar é fácil e rápido, basta adicionar <span class="mark">.tr</span> em seus textos!<br>
<span class="mark">Text('bem vindo'.tr),</span>
<br><br>
Vamos ver como ela se encaixa em nossas estruturas.<br>
Crie o diretório <span class="mark">translations</span> e o arquivo <span class="mark">app_translations.dart</span>
que conterá todas as traduções de maneira organizada, permitindo uma ou mais línguas. Crie Também os respectivos
diretórios para cada língua, iremos falar sobre eles depois.<br>
<div class="tab">
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openCity('translation-package')">Em Packages</button>
<button class="w3-bar-item w3-button" onclick="openCity('translation-modular')">Em Módulos</button>
</div>
<div id="translation-package" class="w3-container w3-display-container city">
<span onclick="this.parentElement.style.display='none'"
class="w3-button w3-large w3-display-topright">×</span>
<pre>
|-- lib
|-- app
|-- data
|-- provider
api.dart
|-- model
model.dart
|-- repository
posts_repository.dart
|-- controller
|-- home_controller
home_controller.dart
|-- ui