Incluída a nova seção de dicas úteis como na documentação em inglês
Showing
1 changed file
with
205 additions
and
1 deletions
| @@ -612,11 +612,215 @@ ObxValue( | @@ -612,11 +612,215 @@ ObxValue( | ||
| 612 | ), | 612 | ), | 
| 613 | ``` | 613 | ``` | 
| 614 | 614 | ||
| 615 | -## Explicação em vídeo sobre Outras Features do GetX | 615 | +### Explicação em vídeo sobre Outras Features do GetX | 
| 616 | 616 | ||
| 617 | Amateur Coder fez um vídeo incrível sobre utils, storage, bindings e outras features! Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU) | 617 | Amateur Coder fez um vídeo incrível sobre utils, storage, bindings e outras features! Link: [GetX Other Features](https://youtu.be/ttQtlX_Q0eU) | 
| 618 | 618 | ||
| 619 | 619 | ||
| 620 | +## Dicas Úteis | ||
| 621 | + | ||
| 622 | +`.obs`ervables (também conhecidos como _Rx_ Types) possuem uma grande variedade de métodos e operadores internos. | ||
| 623 | + | ||
| 624 | +> É muito comum acreditar que uma propriedade com `.obs` **É** o valor real... mas não se engane! | ||
| 625 | +> Evitamos a declaração de tipo da variável, porque o compilador do Dart é inteligente o suficiente e o código | ||
| 626 | +> parece mais limpo, mas: | ||
| 627 | + | ||
| 628 | +```dart | ||
| 629 | +var message = 'Hello world'.obs; | ||
| 630 | +print( 'Message "$message" é do tipo ${message.runtimeType}'); | ||
| 631 | +``` | ||
| 632 | + | ||
| 633 | +Mesmo que `message` _imprima_ o valor da string, seu tipo é **RxString**! | ||
| 634 | + | ||
| 635 | +Então, você não pode fazer `message.substring( 0, 4 )`. | ||
| 636 | +Você tem que acessar o `valor` real dentro do _observable_: | ||
| 637 | +A "maneira" mais usada é utilizando `.value`, mas, você sabia que também pode usar: | ||
| 638 | + | ||
| 639 | +```dart | ||
| 640 | +final name = 'GetX'.obs; | ||
| 641 | +// apenas "atualiza" o stream, se o valor for diferente do atual. | ||
| 642 | +name.value = 'Hey'; | ||
| 643 | + | ||
| 644 | +// Todas as propriedades Rx são "chamáveis" e retorna o novo valor. | ||
| 645 | +// but this approach does not accepts `null`, the UI will not rebuild. | ||
| 646 | +// mas esta abordagem não aceita `null`, a UI não será reconstruída | ||
| 647 | +name('Hello'); | ||
| 648 | + | ||
| 649 | +// é como um getter, imprime 'Hello' | ||
| 650 | +name() ; | ||
| 651 | + | ||
| 652 | +/// números: | ||
| 653 | + | ||
| 654 | +final count = 0.obs; | ||
| 655 | + | ||
| 656 | +// Você pode usar todas as operações não mutáveis das primitivas de num! | ||
| 657 | +count + 1; | ||
| 658 | + | ||
| 659 | +// Cuidado! isso só é válido se `count` não for final, mas var | ||
| 660 | +count += 1; | ||
| 661 | + | ||
| 662 | +// Você também pode comparar com os valores: | ||
| 663 | +count > 2; | ||
| 664 | + | ||
| 665 | +/// booleans: | ||
| 666 | + | ||
| 667 | +final flag = false.obs; | ||
| 668 | + | ||
| 669 | +// mude o valor entre true/false | ||
| 670 | +flag.toggle(); | ||
| 671 | + | ||
| 672 | + | ||
| 673 | +/// todos os yipos: | ||
| 674 | + | ||
| 675 | +// Defina `value` como null. | ||
| 676 | +flag.nil(); | ||
| 677 | + | ||
| 678 | +// Todas as operações toString() e toJson() são passada para `value` | ||
| 679 | +print( count ); // chama `toString()` de RxInt | ||
| 680 | + | ||
| 681 | +final abc = [0,1,2].obs; | ||
| 682 | +// Converte o valor em um Array json, imprime RxList | ||
| 683 | +// Json é suportado por todos os Rx types! | ||
| 684 | +print('json: ${jsonEncode(abc)}, type: ${abc.runtimeType}'); | ||
| 685 | + | ||
| 686 | +// RxMap, RxList e RxSet são Rx types especiais, que estendem seus tipos nativos. | ||
| 687 | +// mas você pode trabalhar com uma lista como uma lista normal, embora seja reativa! | ||
| 688 | +abc.add(12); // Coloca 12 na lista, e ATUALIZA o stream. | ||
| 689 | +abc[3]; // como uma lista lê o índice 3. | ||
| 690 | + | ||
| 691 | +// equality works with the Rx and the value, but hashCode is always taken from the value | ||
| 692 | +// a igualdade funciona com o Rx e o valor, mas hashCode é sempre obtido do valor | ||
| 693 | +final number = 12.obs; | ||
| 694 | +print( number == 12 ); // prints > true | ||
| 695 | + | ||
| 696 | +/// Rx Models personalizados: | ||
| 697 | + | ||
| 698 | +// toJson(), toString() são transferidos para o filho, para que você possa implementar override neles e imprimir o observável diretamente. | ||
| 699 | + | ||
| 700 | +class User { | ||
| 701 | + String name, last; | ||
| 702 | + int age; | ||
| 703 | + User({this.name, this.last, this.age}); | ||
| 704 | + | ||
| 705 | + @override | ||
| 706 | + String toString() => '$name $last, $age years old'; | ||
| 707 | +} | ||
| 708 | + | ||
| 709 | +final user = User(name: 'John', last: 'Doe', age: 33).obs; | ||
| 710 | + | ||
| 711 | +// `user` é "reativo", mas as propriedades dentro NÃO SÃO! | ||
| 712 | +// ntão, se mudarmos alguma variável dentro dele: | ||
| 713 | +user.value.name = 'Roi'; | ||
| 714 | +// O widget não vai reconstruir!, | ||
| 715 | +// `Rx` não tem nenhuma notificação quando você muda algo dentro do usuário. | ||
| 716 | +// Portanto, para classes personalizadas, precisamos "notificar" manualmente a mudança. | ||
| 717 | +user.refresh(); | ||
| 718 | + | ||
| 719 | +// ou podemos usar o método `update()`! | ||
| 720 | +user.update((value){ | ||
| 721 | + value.name='Roi'; | ||
| 722 | +}); | ||
| 723 | + | ||
| 724 | +print( user ); | ||
| 725 | +``` | ||
| 726 | + | ||
| 727 | +#### GetView | ||
| 728 | + | ||
| 729 | +Eu amo este Widget, é tão simples, mas tão útil! | ||
| 730 | + | ||
| 731 | +É um Widget `const Stateless` que tem um getter `controller` registrado para Controller, só isso. | ||
| 732 | + | ||
| 733 | +```dart | ||
| 734 | +class AwesomeController extends GetxController { | ||
| 735 | + final String title = 'My Awesome View'; | ||
| 736 | +} | ||
| 737 | + | ||
| 738 | +// SEMPRE lembre de passar o `Type` que você usou para registrar seu controlador! | ||
| 739 | +class AwesomeView extends GetView<AwesomeController> { | ||
| 740 | + @override | ||
| 741 | + Widget build(BuildContext context) { | ||
| 742 | + return Container( | ||
| 743 | + padding: EdgeInsets.all(20), | ||
| 744 | + child: Text( controller.title ), // apenas chame `controller.something` | ||
| 745 | + ); | ||
| 746 | + } | ||
| 747 | +} | ||
| 748 | +``` | ||
| 749 | + | ||
| 750 | +#### GetWidget | ||
| 751 | + | ||
| 752 | +A maioria das pessoas não tem ideia sobre este widget, ou confunde totalmente o uso dele. | ||
| 753 | +O caso de uso é muito raro, mas muito específico: Ele armazena em `cache` um Controller. | ||
| 754 | +Por causa do _cache_, não pode ser um `const Stateless`. | ||
| 755 | + | ||
| 756 | +> Então, quando você precisa armazenar em "cache" um Controller? | ||
| 757 | + | ||
| 758 | +If you use, another "not so common" feature of **GetX**: `Get.create()`. | ||
| 759 | +Se você usar, uma outra característica "não tão comum" de **GetX**: `Get.create()`. | ||
| 760 | + | ||
| 761 | +`Get.create(()=>Controller())` irá gerar um novo `Controller` cada vez que você chamar | ||
| 762 | +`Get.find<Controller>()`, | ||
| 763 | + | ||
| 764 | +That's where `GetWidget` shines... as you can use it, for example, | ||
| 765 | +to keep a list of Todo items. So, if the widget gets "rebuilt", it will keep the same controller instance. | ||
| 766 | + | ||
| 767 | +É aí que `GetWidget` brilha... já que você pode usá-lo, por exemplo, | ||
| 768 | +para manter uma lista de itens Todo. Portanto, se o widget for "reconstruído", ele manterá a mesma instância do controlador. | ||
| 769 | + | ||
| 770 | +#### GetxService | ||
| 771 | + | ||
| 772 | +Esta classe é como um `GetxController`, ele compartilha o mesmo ciclo de vida ( `onInit()`, `onReady()`, `onClose()`). | ||
| 773 | +Mas não tem "lógica" dentro dele. Ele apenas notifica o sistema de injeção de dependência do GetX de que esta subclasse | ||
| 774 | +**não pode** ser removida da memória. | ||
| 775 | + | ||
| 776 | +Portanto, é muito útil manter seus "Services" sempre acessíveis e ativos com `Get.find()`. Como: | ||
| 777 | +`ApiService`, `StorageService`, `CacheService`. | ||
| 778 | + | ||
| 779 | +```dart | ||
| 780 | +Future<void> main() async { | ||
| 781 | + await initServices(); /// Aguarda a inicialização dos Services. | ||
| 782 | + runApp(SomeApp()); | ||
| 783 | +} | ||
| 784 | + | ||
| 785 | +/// É uma jogada inteligente para inicializar seus services antes de executar o aplicativo Flutter, | ||
| 786 | +/// já que você pode controlar o fluxo de execução (talvez você precise carregar alguma configuração de tema, | ||
| 787 | +/// apiKey, linguagem definida pelo usuário ... então carregue SettingService antes de executar ApiService. | ||
| 788 | +/// então GetMaterialApp() não precisa reconstruir e obtém os valores diretamente. | ||
| 789 | +void initServices() async { | ||
| 790 | + print('iniciando serviços...'); | ||
| 791 | + /// Aqui é onde você coloca a inicialização de get_storage, hive, shared_pref. | ||
| 792 | + /// ou checa a conexão, ou o que quer que seja assíncrono. | ||
| 793 | + await Get.putAsync(() => DbService().init()); | ||
| 794 | + await Get.putAsync(SettingsService()).init(); | ||
| 795 | + print('Todos os serviços iniciados.'); | ||
| 796 | +} | ||
| 797 | + | ||
| 798 | +class DbService extends GetxService { | ||
| 799 | + Future<DbService> init() async { | ||
| 800 | + print('$runtimeType delays 2 sec'); | ||
| 801 | + await 2.delay(); | ||
| 802 | + print('$runtimeType ready!'); | ||
| 803 | + return this; | ||
| 804 | + } | ||
| 805 | +} | ||
| 806 | + | ||
| 807 | +class SettingsService extends GetxService { | ||
| 808 | + void init() async { | ||
| 809 | + print('$runtimeType delays 1 sec'); | ||
| 810 | + await 1.delay(); | ||
| 811 | + print('$runtimeType ready!'); | ||
| 812 | + } | ||
| 813 | +} | ||
| 814 | +``` | ||
| 815 | + | ||
| 816 | +The only way to actually delete a `GetxService`, is with `Get.reset()` which is like a | ||
| 817 | +"Hot Reboot" of your app. So remember, if you need absolute persistance of a class instance during the | ||
| 818 | +lifetime of your app, use `GetxService`. | ||
| 819 | + | ||
| 820 | +A única maneira de realmente excluir um `GetxService`, é com o `Get.reset()`, que é como uma | ||
| 821 | +"reinicialização a quente" do seu aplicativo. Portanto, lembre-se, se você precisar de persistência absoluta de uma instância de classe durante | ||
| 822 | +o ciclo de vida de seu aplicativo, use GetxService. | ||
| 823 | + | ||
| 620 | 824 | ||
| 621 | # Breaking Changes da versão 2 para 3 | 825 | # Breaking Changes da versão 2 para 3 | 
| 622 | 826 | 
- 
Please register or login to post a comment