[Gastosabertos-dev] ao

Edgar Zanella Alvarenga e em vaz.io
Terça Março 3 01:04:22 UTC 2015


Ok, vi com mais calma o código agora e seu email esclareceu melhor
alguns pontos. Estava confuso com os eventos 'page.dt' e 'length.dt',
não sabia que eram eventos do próprio DataTables e pensei que os
tinha criado também.

Gostei de como fez, só acho que da linha 85 a 114 ficou um pouco
obfuscated, apesar de entender a razão de querer ter feito um código
genéricopra lista de parâmetros em 'param'. Acho que seria melhor
ter um subscribe explícito por parâmetro e separar em funções distintas
cada uma das cláusulas condicionais entre 103 e 107, entende, ao
invése de um setParam genérico.

Isso deixaria mais claro o código e mais separado a lógica a ser
realizada a cada mudança de parâmetro.

Tirando isso, maravilha, acho legal irmos por esse direção, me parece
uma solução simples e elegante.

Quanto a dependência com o jquery, sim, devemos colocar isso via 
require,
a idéia é que todo gerenciamento de dependência deja feito por ele,
então considere esses imports via script como algo que vamos ter
que resolver.

Ah sim, o parâmetro code pro endpoint listrevenue já está funcionando:

http://demo.gastosabertos.org/api/v1/receita/list?code=1.1.2&page=0&per_page_num=10&years=2014

Basta adicionar o code com parte do nível superior cujo subníveis quer 
consultar.

E pra finalizar, sobre o Riot, eu só tinha visto o observer dele, mas
nunca usei e não faço idéia se na prática ele iria nos ajudar ou 
complicar
mais no nosso caso de uso, pelo menos no problema de sincronização de
eventos. Eu só fiquei pensando se não era algo já resolvido por um
desses frameworks da modinha ou libs simples como:

https://github.com/mroderick/PubSubJS
https://github.com/uxder/Radio

Que talvez evitem que tenhamos muito trabalho em resolver problemas que
não são nossa prioridade no momento. Novamente, não conheço a fundo
nenhuma dessa libs que citei e a única vantagem que vejo nelas é 
estarem
desacopladas do JQuery, caso fossemos pra uma solução JQuery free.

Mas entendo o ponto de que estamos tentando sincronizar componentes de
libs diferentes, com arquiteturas diferentes e no final se fossemos pra
uma solução "mágica" acabaríamos tendo que fazer vários códigos ao 
redor
dessas bibliotecas pra conversarem entre si. E fiquei pensando na parte
pra sincronizar as mudanças nas variáveis com alterações no URL, 
leitura
do URL pros parâmetros nas diferentes visualizações e me perguntei se
não tinha uma solução onde ganharíamos tudo isso pronto de lambuja (a 
man
can dream!).

Enfim, acho uma boa irmos pela direção que tomou, só talvez tornar isso
mais independente para que seja replicado nas outras páginas, 
provavelmente
fazendo uma biblioteca, RSpubsub (Really Simple PubSub), mas esse não 
precisa
ser nossa prioridade agora.

Abs,
E.

On 02/03/2015 19:27, Luiz Armesto wrote:
> 2015-03-02 17:30 GMT-03:00 Edgar Zanella Alvarenga <e em vaz.io [39]>:
>
>> Oi Luiz, ótimo! Dei uma olhada rápida no seu código e fiz alguns
>> testes.
>> Está legal, mas ocorreu mais de uma vez ao visitar o
>> http://site.gastosabertos.org/receita [1]
>> que o gráfico drilldown carregou, mas a tabela não. Uma vez
>> consegui identificar
>> o erro, que foi não conseguir importar o Datatables, talvez o
>> servidor deles
>> estava fora do ar.
>
> Vou verificar isso. Além de problema no servidor deles pode ter sido
> timeout do requirejs ou talvez tentou carregar o datatables antes do
> jquery (atualmente o jquery está sendo carregado direto no html, com
> tag script, mas o datatables via requirejs. Isso porque o jquery já
> estava sendo usado direto sem o requirejs e o datatables identifica 
> se
> tem alguma lib de AMD, no caso o requirejs, e se registra direto 
> nela,
> não deixando carregar colocando direto uma tag script com ele, então
> tive que carregar usando o requirejs. Precisamos arrumar isso, ou 
> usar
> requirejs ou não usar, misturar é pedir problemas). 
>
>  
>
>> Mas olhando seu código, fiquei encafifado com a quantidade de
>> código
>> que escreveu pra registrar os eventos e não ficou claro pra mim o
>> quão
>> fácil será fazer isso sincronizado com o gráfico de barras. Se
>> tivermos
>> uma forma fácil de utilizar o modelo pusub que está usando legal
>> sem muito
>> biolerplate code, ótimo. Mas fico em dúvida se utilizarmos uma
>> solução
>> como o Riot js não seja melhor, pra não termos que resolver
>> novamente
>> certos problemas. 
>
>  O que você acha? Por mim sem problemas
>
>> s em uma mesma página. O quanto
>> de código precisará ser replicado? Se conseguir fazer um resumo
>> bem breve
>> do que tem em mente pra anotar os eventos e criar as funções pra
>> respondê-los
>> seria legal.
>>
>> Pelo que olhei no riotjs não enxerguei uma solução mais simples
>> usando ele do que a que pensei. Nós temos que integrar componentes
>> que são feitos com lib
> s, então para sincronizar temos que escutar os eventos que essas libs
> emitem quando o usuário interage com elas e chamar métodos que elas
> definem na API para alterar seus valores na hora de sincronizar. Não
> vejo como as funcionalidades do riotjs de virtual DOM com
> interpolação (o DOM que exibem os gráficos e as tabelas são
> criadas pelas próprias libs externas, não temos controle sobre isso)
> podem ajudar.
>
> O que poderiamos usar do riotjs é a API de Observer deles, mas o
> jQuery já implementa isso (é o que estou usando) e já o temos como
> dependência.
>
> Vocês chegaram a pensar em como sincronizar os vários componentes
> usando o riotjs e viram usos dele que eu não enxerguei?
>
> Sobre a implementação do Sub/Pub, na verdade é apenas uma facade
> para a implementação de eventos do jQuery, são 7 linhas [0] que
> definem um objeto e redirecionam 3 métodos para o jQuery:
>
>  subscribe --> on
>  unsubscribe --> off
>  publish -- trigger
>
> Para usar é simplesmente criar uma instância e se registrar com o
> "subscribe" para receber as notificações de uma determinada mensagem
> e mandar notificações com o "publish":
>
> // Cria o objeto
> var pubSub = new PubSub();
>
> // Registra para receber notificações
> pubSub.subscribe(nome_da_mensagem, function(evt, content) {
>   console.log(Mensagem recebida com o seguinte conteúdo: , content);
> });
>
> // Publica notificação
> pubSub.publish(nome_da_mensagem, este é o conteúdo);
>
> // Neste ponto foi exibido "Mensagem recebida com o seguinte
> conteúdo: este é o conteúdo"
>
> Então para usar o pub/sub é bem fácil e com muito pouco código,
> só precisa que todos os envolvidos na sincronização tenham acesso
> ao mesmo objeto de pub/sub e compartilhem de uma padronização nos
> nomes e formatos das mensagens enviadas, sem ter conhecimento de quem
> são os demais participantes (desacoplados). Então se, por exemplo, a
> tabela registrou para receber uma mensagem quando o código é
> alterado, ela tera o mesmo comportamento independente se a alteração
> é proveniente de uma mudança na url, um clique no gráfico ou uma
> seleção num menu, só precisa que a mensagem seja publicada no
> objeto pub/sub seguindo o padrão definido.
>
> O que acontece, em relação a quantidade de código que escrevi, para
> ter mais linhas [1] do que 3 simples "pubSub.subscribe(...)" (que
> seria um para "page", um para "per_page_num" e um para "years", que
> são as três coisas que atualmente importam para a tabela) é porque
> eu fiz de um modo que o mesmo objeto pode ser reutilizado para 
> tabelas
> diferentes, que buscam os dados em outros endpoints que tenham
> parâmetros diferentes (ou mesmo para estender o funcionamento da
> tabela atual quando os outros parâmetros forem implementados, como o
> "codes", sem precisar alterar o código).
>
> Eu defino na criação do objeto quais são os parâmetros do endpoint
> que importam para a tabela, ou que poderão ser alterados externamente
> por outro componente, podendo definir um valor inicial [2], então eu
> itero sobre os parâmetros registrando automaticamente [3].
>
> Assim, se eu criar um objeto DataTable passando nas opções "params:
> { years: 2014, page: 0, per_page_num: 10  }" ele vai se registrar
> para as mensagens "years:changed", "page:changed" e
> "per_page_num:changed" e quando qualquer um publicar uma dessas
> mensagens ele vai se atualizar. Quando tivermos implementado o
> parâmetro "codes" na endpoint "List revenues" basta alterar na
> criação do objetos incluindo esse parâmetro nas opções (passando
> a ser "params: { years: 2014, page: 0, per_page_num: 10 , codes: null
> }") que a tabela passará a responder também a mensagem
> "codes:changed", armazenando internamente o valor (método "setParam"
> chamado pelo callback do "pubSub.subscribe"), que será enviado na
> requisição AJAX (no método "_ajaxRequest", que é usado pela lib
> DataTables, e é responsável por enviar todos os parâmetros
> registrados).
>
> Então para criar tabelas com dados diferentes, endpoint diferente e
> parâmetros diferentes, mas também facilmente sincronizável e com
> paginação via ajax, basta criar um objeto DataTable informando qual
> a url do endpoint, quais são os parametros e quais são os campos do
> json de cada coluna e pronto. Fazer o que está entre as linhas 199 e
> 222 [4] com as devidas alterações, em especial em "columns" e
> "params", sem precisar nem criar mais funções nem definir outros
> tipos de objetos. 
>
> TL; DR;
>
> Para sincronizar, o componente com o qual o usuário está
> interagindo, por exemplo no caso do ano ser alterado, só terá que
> chamar "pubSub.publish(years:changed, {value: [anoMin, anoMax]})" e 
> os
> demais terem se registrado com "pubSub.subscribe(years:changed,
> callback)", e implementado a logica necessária no callback, para
> serem notificados e se manterem sincronizados.
>
> O DataTable é mais complicado do que isso pois foi feito de modo
> genérico para ser reutilizado em outras páginas, pecisando apenas
> configurar algumas coisas na criação do objeto.
>
> 
> [0] https://github.com/okfn-brasil/gastos_abertos_website/blob/cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/javascripts/receitas/main.js#L188
> [40]
> 
> [1] https://github.com/okfn-brasil/gastos_abertos_website/blob/cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/javascripts/receitas/main.js#L71
> [41]
> 
> [2] https://github.com/okfn-brasil/gastos_abertos_website/blob/cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/javascripts/receitas/main.js#L211
> [42]
> 
> [3] https://github.com/okfn-brasil/gastos_abertos_website/blob/cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/javascripts/receitas/main.js#L86
> [43]
> 
> [4] https://github.com/okfn-brasil/gastos_abertos_website/blob/cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/javascripts/receitas/main.js#L199
> [44]
>
> []s
>
>  
>  Abs,
>  E.
>
>  On 02/03/2015 14:07, Luiz Armesto wrote:
>
>
> Links:
> ------
> [1] http://site.gastosabertos.org/receita
> [2] https://github.com/okfn-brasil/gastos_abertos/pull/134
> [3] https://github.com/okfn-brasil/gastos_abertos/issues/121
> [4] https://github.com/okfn-brasil/gastos_abertos/issues/132
> [5] mailto:Gastosabertos-dev em lists.okfn.org
> [6] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [7] mailto:Gastosabertos-dev em lists.okfn.org
> [8] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [9] mailto:Gastosabertos-dev em lists.okfn.org
> [10] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [11] mailto:Gastosabertos-dev em lists.okfn.org
> [12] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [13] mailto:Gastosabertos-dev em lists.okfn.org
> [14] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [15] mailto:Gastosabertos-dev em lists.okfn.org
> [16] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [17]
> 
> http://demo.gastosabertos.org/receita/static/total_by_year_by_code/2014.json
> [18] mailto:e em vaz.io
> [19]
> 
> http://demo.gastosabertos.org/receita/static/total_by_year_by_code/2014.json
> [20] 
> http://demo.gastosabertos.org/api/v1/receita/totaldrilldown?year=2014
> [21] 
> http://demo.gastosabertos.org/api/v1/receita/totaldrilldown?year=2014
> [22] mailto:Gastosabertos-dev em lists.okfn.org
> [23] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [24] mailto:Gastosabertos-dev em lists.okfn.org
> [25] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [26] mailto:Gastosabertos-dev em lists.okfn.org
> [27] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [28] mailto:Gastosabertos-dev em lists.okfn.org
> [29] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [30] https://github.com/okfn-brasil/gastos_abertos/pull/134
> [31] https://github.com/okfn-brasil/gastos_abertos/issues/121
> [32] mailto:Gastosabertos-dev em lists.okfn.org
> [33] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [34] mailto:Gastosabertos-dev em lists.okfn.org
> [35] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [36] mailto:e em vaz.io
> [37] mailto:Gastosabertos-dev em lists.okfn.org
> [38] https://lists.okfn.org/mailman/listinfo/gastosabertos-dev
> [39] mailto:e em vaz.io
> [40]
> 
> https://github.com/okfn-brasil/gastos_abertos_website/blob/cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/javascripts/receitas/main.js#L188
> [41]
> 
> https://github.com/okfn-brasil/gastos_abertos_website/blob/cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/javascripts/receitas/main.js#L71
> [42]
> 
> https://github.com/okfn-brasil/gastos_abertos_website/blob/cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/javascripts/receitas/main.js#L211
> [43]
> 
> https://github.com/okfn-brasil/gastos_abertos_website/blob/cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/javascripts/receitas/main.js#L86
> [44]
> 
> https://github.com/okfn-brasil/gastos_abertos_website/blob/cd83cc446e6953b2281c7cebbdabc8f7d5e79772/frontend/src/javascripts/receitas/main.js#L199




Mais detalhes sobre a lista de discussão Gastosabertos-dev