Eduardo Florence

Incluída a nova seção de dicas úteis como na documentação em inglês

@@ -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