braziljs/ideias

Engine XML Web Components

Opened this issue · 20 comments

O principio de web components extendido para aplicação em tags xml que tem toda sua implementação em código javascript.

Pode dar um exemplo?

Imagine uma tag xml e suas propriedades . Essa tag xml representa um objeto javascript com suas respectivas propriedades. A partir dai a Engine XML Web Components lê o arquivo xml com várias tags xml e instância os objetos javascript.

Ainda não consegui visualizar como nem mesmo o porquê isso seria feito, tem como explicar melhor seu caso de uso @brunoborgesruiz?

Meu caso de uso consiste um uma equipe focada em back-end com algum conhecimento em xml e a necessidade de gerar relatórios em diferentes formatos. Para aumentarmos a produtividade em termos de saída de relatórios, e ainda assim usando componentes que estejam dentro dos padrões web (html5), esse projeto faz algum sentido , já que a curva de aprendizagem para uso dos componentes seria bem menor.

Como isso se conecta com Web Components? Pode mostrar em forma de código como seria essa ideia?

Além disso, que tipo de ajuda especificamente você precisaria para fazer isso acontecer?

O que segue abaixo é um botão em javascript:

var ModeloBotao = function () {
"use strict";
this.identificacao = Math.random() * 100;
this.texto = "";
this.tipo = "";
this.tamanho = "";
this.icone = "";
this.funcao = "";
};

var VisaoBotao = function () {
"use strict";
this.visao = function () {
var v = document.createElement('button'),
ic = document.createElement('i');
v.appendChild(ic);
return v;
};

};

var ControladorBotao = function () {
"use strict";
this.modelo = new ModeloBotao();
this.visao = new VisaoBotao();
this.implementa = function (modelo) {
var v = this.visao.visao();

    v.setAttribute('id', modelo.identificacao);
    v.innerHTML += modelo.texto;
    v.className = modelo.tipo;
    v.className += " " + modelo.tamanho;
    v.children[0].className = modelo.icone;
    v.addEventListener("click", eval(modelo.funcao));
    return v;
};

};

O que segue abaixo é a marcação em xml para o objeto acima:

O que segue abaixo é um "rascunho" de uma Engine XML que fiz para que leia o arquivo xml com a marcação e crie a marcação html com base no objeto javascript:

function carregaXML(arquivo){

var requisicaoXML = new XMLHttpRequest();   
    requisicaoXML.open("GET",arquivo,false);
    requisicaoXML.send();

    return requisicaoXML.responseXML;

}

var leXML = function (retornoDeArquivoXML){
/Cria variável baseada na tag/
eval("tag"+retornoDeArquivoXML.getAttribute('id')+"= new Controlador"+retornoDeArquivoXML.tagName+"()");

    /*Varre todos os atributos da tag corrente*/
    for (var k = 0; k < retornoDeArquivoXML.attributes.length; k++) {

            /*Atribui ao elementos as prorpiedades lidas*/  
            eval("tag"+retornoDeArquivoXML.getAttribute('id')+".modelo."+retornoDeArquivoXML.attributes[k].name+" = '"+
                retornoDeArquivoXML.attributes[k].value+"'");

    };

    /*Atribui as propriedades lidas e atribuitas nos objetos nas tags*/ 
    //eval("tag"+retornoDeArquivoXML.getAttribute('id')+".implementa("+"tag"+retornoDeArquivoXML.getAttribute('id')+".modelo"+")");

    /*Verifica se existe pai*/
    if(retornoDeArquivoXML.parentNode.tagName != undefined){
        eval("tag"+retornoDeArquivoXML.parentNode.getAttribute('id')+".adicionaElemento(" +"tag"+retornoDeArquivoXML.getAttribute('id')+".implementa("+"tag"+retornoDeArquivoXML.getAttribute('id')+".modelo"+")");
    }else{
        eval("document.querySelector('#body').appendChild(tag"+retornoDeArquivoXML.getAttribute('id')+".implementa("+"tag"+retornoDeArquivoXML.getAttribute('id')+".modelo"+"))");
    }

    /*Varre todos os filhos da tag corrente*/
    for (var k = 0; k < retornoDeArquivoXML.childNodes.length; k++) {

        /*Avalia o tipo do filho da tag corrente*/
        if(retornoDeArquivoXML.childNodes[k].nodeType == '1'){
                /*Realiza a varredura da tag corrente*/
                leXML(retornoDeArquivoXML.childNodes[k])
        }
    };

}

A ajuda seria para aprimorar a ideia, a implementação usada e criar os grupos de componentes para o projeto.

Deixa ver se entendi: a ideia é instanciar componentes dinamicamente baseado nos dados enviados pelo XML. É isso?

O github comeu seu exemplo de xml, mas se entendi vc quer algo tipo o transform de JSX do react, que transforma tags em html e aplica comportamento definido em javascript, viajei?

Não viajou, mas a ideia seria uma solução para quem não tem familiaridade com o javascript e possa construir toda uma aplicação usando os componentes em xml.

@brunoborgesruiz voce conhece XSL?

A segunda resposta parece fazer mais ou menos o que voce está querendo http://stackoverflow.com/questions/5722410/how-can-i-use-javascript-to-transform-xml-xslt, da uma conferida fazendo favor. Nesse caso só ficou faltando o controlador do component, mas essa parte é tranquilo uma vez que voce ja puxou o xml transformado em html.

Seu caso de uso é bem específico, me diga se é por esse caminho mesmo ou nada a ver ;)

@brunoborgesruiz Eu consegui ver bem a ideia, mas pelo que entendi, esse projeto seria para uma ajuda a fim de empresa privada. Ajudando no workflow e/ou demanda para a empresa, eu não consegui ver isso como projeto "globalmente" que ajudaria mais pessoas ou empresas. Acredito que a ideia e não ajudar uma solução especifica para uma empresa.

Se estiver errado, me corrija por favor.

@bernardodiasc acho que você entendeu a ideia sim. A ideia é essa. Qual seria o objetivo do projeto: criar uma engine e um padrão para desenvolvimento dos componentes, que possa atender a qualquer necessidade. Assim a comunidade teria a engine e uma série de componentes prontos para uso. Mas se quisesse fazer uso apenas da engine e criar seus próprios componentes, ele poderia fazer isso.

@keppelen @zenorocha a ideia desse projeto surgiu de uma necessidade de uma empresa sim. Mas podemos nos perguntar quantos na comunidade se deparam com este mesmo problema? E quantos dos nossos colegas desenvolvedores podem sanar esses problemas internamente por meio dessa solução? Não quero desenvolver aqui uma solução específica. Quero ajudar a comunidade com uma solução que possa ser o mais genérica possível. Ser simples para implementar.Ser muito simples para implementar.

Fiz um projeto onde criei alguns templates de componentes, cada qual com seu schema de dados necessário pra renderizar a marcação HTML. O Javascript de cada era bem simples, algo como:

[].forEach.call(document.querySelectorAll('NOMEDATAG'), function(module){
  /// blah blah blah
});

É um projeto de brincadeira, pra explorar conceitos, https://github.com/bernardodiasc/elements/ (https://github.com/bernardodiasc/elements/blob/gh-pages/HOWTO.md) se quiser conferir e ver se a solução é parecida. Tem XSL + XML e Twig + Json, compila tudo usando Gulp e retorna HTML estático. A diferença que tem aqui é que voce não usa JS pra montar a marcação, voce entrega ela pronta. Vale ressaltar que é um projeto experimento, mal documentado e incompleto. E lembrando que existem soluções melhores que essa. A similaridade do projeto com a sua ideia é mais em relação ao schema de dados. Em XLT isso fica muito mais evidente já que é uma linguagem de transformação, não template.

Dei uma pesquisa rapida sobre esse assunto, aparentemente existem muitas formas diferentes de fazer isso. Imagino que talvez seu caso de uso te forçe a fazer assim já que voce recebe do backend o XML com as informações que voce precisa pra montar o html e instanciar o objeto.

Porém não acho que trabalhar dessa forma seja mais fácil que em outras alternativas mais comuns, tem muitas libs e microtemplates que podem usar Json pra montar a marcação via Javascript. Com XML, a solução mais natural seria mesmo com XSL, puxando a marcação já montada via Ajax ao invez de montar pelo Javascript e depois instanciar as funções desse elemento.

Uma outra coisa a se considerar é que XML trabalha naturalmente com Mixed Content, voce poderia enviar inclusive a marcação HTML já montada direto pelo XML.

Enfim, a ideia é interessante, mas não sei se é a melhor forma de conseguir os resultados esperados.

Ah, me foquei mais na parte de montar a marcação pois não acho muito boa ideia gerar javascript automaticamente. Não sei até que ponto isso funciona. Seria legal alguns exemplos.