No post #2 vimos como implementar reatividade com GetBuilder, mas não acabou.

Na leitura da documentação de hoje (05/6/20) notei que havia algo que não tinha visto em leituras anteriores: GetX;

Na primeira leitura me pareceu muito interessante, mas precisava de exemplos para entender o processo, então vamos lá tentar dismitificar este tal.

Entendendo, é uma implementação reativo utilizando Stream, ou seja, lá no seu interior temos Stream notificando as alteraçoes. Então, neste formado ele é mais próximo de um BLoC.

Consumindo “extension” para adicionar reatividade

Em outro post já escrevi sobre as “extension”, isto mesmo… os observers de GetX utilizam “extension” para incluir reatividade.

Exemplo: var contador = 0.obs;

No exemplo ‘.obs’ é uma propriedade/método do “int” que gera uma Stream para “contador” ou se preferir teremos um “listener” que notifica seus assinantes.

O que fazer com isto? Como Stream é possível fazer do jeito mais difícil (só para brincar como Stream):

/// testando o '.obs como stream"
Widget everBuilder(RxInterface listener, Widget Function(dynamic) callback,
    {bool condition = true}) {
  return StreamBuilder(
      stream: listener.subject.stream,
      builder: (x, y) {
        if (y.hasData) return callback(y.data.$new);
        return Container();
      });
}

com everBuilder (….) é possível consumir o ‘contador’ como um Stream tradicional do Dart, da seguinte forma:

 @override
  Widget build(BuildContext context) { 
      /// usando StreamBuilder
      return    everBuilder(contador, (x) {
            return Text('$x');
          });
.....

mas, se o que precisa é um “listener” tradicional, então pode usar o “ever(…)” como a seguir:

 ever(contador, (x) {
      print('ever: ${contador.value} - $x'); });

StreamBuilder – pode esquecer, agora “Obx(…)”

Quando escrevi o “everBuilder” ainda não havia me atentado para uma parte bem rápida da documentação que mostra o “Obx(…)”… então esquece, StsreamBuilder ficou ultrapassado. Mantive o “everBuilder” somente para poder ilustrar, mas poderia muito bem ter descartado e ir direto para o Obx..

Diga, lá… então como usar este tal?

Imagina aquele contador de exemplo “acima”, se desejar que la no meio da construção ele faça uma atualização de um Widget, Obx resolve – ele é um builder que lida com tipos de dados ‘.obs’ como no caso do “contador” fazendo assim:

@override
  Widget build(BuildContext context) {
  ....
  return Obx(() => Text('${contador.value}'));
...

Isto mesmo que você esta imaginando, toda vez que algum código mudar o contador (contador.value ++), irá enviar uma mensagem ao “Obx” indicando que o valor mudou, e portanto precisa refazer o “Text(…)”.

Gostou do Obx? então “deixa um gostei” e deixa os seus comentários ou dúvidas. Assim nos motiva a estudar novos recursos.

“Observer” é inigmático. Você nem esperava e chega aquela notícia que alguma coisa aconteceu. A janela estava lá mostrando uma fila de clientes em atendimento, mas de repente alguém gritou que chegou um cliente com preferência no atendimento e a fila precisa ser reorganizada para acomodar aquele cliente com preferência… Certamente você já viu um cenário deste ou participou de uma fila destas.
Vejamos os atores para o cenário: de uma lado existe alguém pronto para receber a informação de necessidade de reorganizar a fila, ele fica lá só esperando alguém gritar – de outro tem um lá na porta da instituição com sede de saber novidades para sair falando para todo mundo.

Trabalhar com “Observer” é em outras palavras montar uma rede de informação de notícias. Existe um ator que assina o serviço de notícia e outro que distribui as notícias – é isto que um “patterns observer” faz.

Olhando para o MVCBr, o primeiro passo é assinar o serviço de notícias (aquele que fica esperando uma notícia para tomar uma ação):

[code]
uses MVCBr.Observable;

… on form show
// assinar o serviço de notícias
TMVCBrObservable.subscribe( form1, ‘reorganizar.fila’,
procedure (json:TJsonValue)
var nQtde:integer;
begin
nQtde = json.getvalue<integer>(‘qtde’);
abrirVagaNaFila(nQtde);
end);

…. on destroy
// retirar a assinatura do serviço
TMVCBrObservable.UnSubscribe(form1);

[/code]

Do outro lado esta o distribuidor de notícias, aquele que grita que precisa entrar um cliente preferêncial na fila:

[code]
uses MVCBr.Observable;
..

// em algum lugar em que a notícia nasce
TMVCBrObservable.send( ‘reorganizar.fila’, TJsonObject.parse( ‘{"qtde":1}’ ) );

[/code]

Quando o “observer” recebe a notícia, ele com sede de espalhar a notícia, sai procurando todo mundo que se candidatou para receber aquele serviço… e pá… manda a notícia uma-a-uma para cada assinante.

Aproveitem: git