Escopo dos ambientes das Widgets. Um código conflita com outro?

Estou com um problema que o suporte diz que é de minha responsabilidade.

Já postei aqui o problema e colega @Allan Khel reproduziu o mau funcionamento.

Então, deve ser mesmo uma falta de competência de minha parte, por não entender o conceito de Widgets e sua área de influência.

Então, se puderem me ajudar, gostaria de saber: o código javascript de uma Widget, posto em chamadas na seção Local, pode interferir em funções com nomes diferentes, referenciando-se a elementos html com ids diferentes, funções estas que estão também na seção local de suas respectivas Widgets?

Ambas funções têm o mesmo procedimento interno a elas, fazem a mesma coisa, mas como dito, com referências a elementos html únicos.

Este é o html da Widget 'Compliance':


<div id="MyWidget_${instanceId}" class="super-widget wcm-widget-class fluig-style-guide" data-params="MyWidget.instance()">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
    <div class="panel panel-default">
    <div class="panel-body">
    <button type="button" id="idBtnNotProcurar" name="namBtnMomProcurar" style="margin-bottom:10px;color:coral;font-weight:bold;" class="btn btn-default" data-procuramomento><h2></h2>Carregar a lista de publicações do Momento Compliance</h2></button>
        <select id="idSelMomArquivos" name="namSelMomArquivos" class="form-control" data-mostraedicao>
        </select>
    </div>
</div>
</div>

Este é o seu javascript:


var MyWidget = SuperWidget.extend({
      //variáveis da widget
    variavelNumerica: null,
    variavelCaracter: null,

    //método iniciado quando a widget é carregada
    init: function() {
            },

    //BIND de eventos
    bindings: {
        local: {
            'execute': ['click_executeAction'],
            'mostraedicao':['change_fMostraEdicao'],
            'procuramomento':['click_fProcuraMomento']
        },
        global: {}
    },
     executeAction: function(htmlElement, event) {
        //alert ("passou no executeAction");
    },
    fProcuraMomento: function (elementoProvocador,eventoPassado){
        //var qtdElementos=jQuery("#idSelMomArquivos").children('option').length;
        localStorage.setItem("concatena","");
        var objSel=jQuery("#idSelMomArquivos");
        objSel.empty();
        var concatena='<option value="0" title="0">Escolha uma edição...</option>';
        jQuery.get("/api/public/ecm/document/listDocument/17",function(retorno){
            jQuery.each(retorno.content,function (k,v){
                var comentarios=v.additionalComments;
                if(comentarios==""){
                    comentarios="O arquivo da notícia "+v.description+" está sem o comentário no metadados. Adicione esta informação na propriedade do arquivo";
                }
                concatena=concatena+'<option value="'+v.id+'" title="'+v.id+'">'+comentarios+'</option>';
                localStorage.setItem("concatena",concatena);
            });//each
            objSel.append(localStorage.getItem("concatena"));
    });//get
    }//fProcuraMomento
    ,
    fMostraEdicao:function(elementoProvocador,eventoPassado){
        var docId=jQuery("#idSelMomArquivos option:selected").val();
        var txtRotulo=jQuery("#idSelMomArquivos option:selected").text();
        var docVersion="1000";
        if(docId * 1 > 0){
        var parentOBJ;

        if (window.opener) {
            parentOBJ = window.opener.parent;
        } else {
            parentOBJ = parent;
        }

        var cfg = {
            url : "/ecm_documentview/documentView.ftl",
            maximized : false,
            title : txtRotulo,
            callBack : function() {
                parentOBJ.ECM.documentView.getDocument(docId, docVersion);
            },
            customButtons : []
        };
                    parentOBJ.ECM.documentView.panel = parentOBJ.WCMC.panel(cfg);
        }//if docId
    }//fMostraEdicao
});

Outra Widget, de nome 'Noticias'. Seu html é


<div id="MyWidget_${instanceId}" class="super-widget wcm-widget-class fluig-style-guide" data-params="MyWidget.instance()">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
    <div class="panel panel-default">
    <div class="panel-body">
    <button type="button" id="idBtnNotProcurar" name="namBtnNotProcurar" style="margin-bottom:10px;color:coral;font-weight:bold;" class="btn btn-default" data-procuranoticia><h2></h2>Carregar a lista de notícias de interesse geral</h2></button>
        <select id="idSelNotArquivos" name="namSelNotArquivos" class="form-control" data-mostranoticia>
        </select>
    </div>
</div>
</div><!--  widget -->

Seu javascript é:


var MyWidget = SuperWidget.extend({
    //variáveis da widget
    variavelNumerica: null,
    variavelCaracter: null,

    //método iniciado quando a widget é carregada
    init: function() {
            },

    //BIND de eventos
    bindings: {
        local: {
            'execute': ['click_executeAction'],
            'mostranoticia':['change_fMostraNoticia'],
            'procuranoticia':['click_fProcuraNoticia']
        },
        global: {}
    },
     executeAction: function(htmlElement, event) {
        //alert ("passou no executeAction");
    },
    fProcuraNoticia: function (elementoProvocador,eventoPassado){
        //var qtdElementos=jQuery("#idSelNotArquivos").children('option').length;
        localStorage.setItem("concatena","");
        var objSel=jQuery("#idSelNotArquivos");
        objSel.empty();
        var concatena='<option value="0" title="0">Escolha uma notícia...</option>';
        jQuery.get("/api/public/ecm/document/listDocument/12",function(retorno){
            jQuery.each(retorno.content,function (k,v){
                var comentarios=v.additionalComments;
                if(comentarios==""){
                    comentarios="O arquivo da notícia "+v.description+" está sem o comentário no metadados. Adicione esta informação na propriedade do arquivo";
                }
                concatena=concatena+'<option value="'+v.id+'" title="'+v.id+'">'+comentarios+'</option>';
                localStorage.setItem("concatena",concatena);
            });//each
            objSel.append(localStorage.getItem("concatena"));
    });//get
    }//fProcuraNoticia
    ,
    fMostraNoticia:function(elementoProvocador,eventoPassado){
        var docId=jQuery("#idSelNotArquivos option:selected").val();
        var txtRotulo=jQuery("#idSelNotArquivos option:selected").text();
        var docVersion="1000";
        if(docId * 1 > 0){
        var parentOBJ;

        if (window.opener) {
            parentOBJ = window.opener.parent;
        } else {
            parentOBJ = parent;
        }

        var cfg = {
            url : "/ecm_documentview/documentView.ftl",
            maximized : false,
            title : txtRotulo,
            callBack : function() {
                parentOBJ.ECM.documentView.getDocument(docId, docVersion);
            },
            customButtons : []
        };
                    parentOBJ.ECM.documentView.panel = parentOBJ.WCMC.panel(cfg);
        }//if docId
    }//fMostraNoticia

});

Qual o escopo, qual o alcance do código javascript entre as Widgets?

Não sei se é o melhor caminho, mas entendi que só pode haver um código javascript para TODAS as widgets que houver no projeto.

Se for isto mesmo, é estranho, porque o Studio cria a estrutura de cada widget com o javascript como se pertence ao escopo da própria Widget, induzindo os iniciantes, como eu, ao erro de achar que se pode programar códigos específicos para cada widget personalizada e que, assim, o escopo ficaria restrito a elas.

Assim, para contornar e dar sequência, criei uma widget sem nada no arquivo EDIT.ftl e VIEW.ftl, mas com códigos javascript que atenderia todas as widgets que eu criaria a partir desse momento.

Fiz uma widget, então, com o nome sugestivo de w_basica e exportei para o meu servidor Fluig.

Depois, a cada Widget que eu criasse e que eu precisasse de código javascript, eu fazia o html em cada uma das novas, mas com código javascript necessário naquela, genérica.

Se não é assim, aprecio uma réplica.

Não é, realmente, o que escrevi aqui neste post, a melhor técnica. Adequado, segundo meu julgamento de iniciante, é a dica de @Marcos Michalski abaixo.

@Mausim já tentou renomear as var MyWidget ... Provavelmente está dando pau, uma está subscrevendo a outra e de fato irá acontecer isso mesmo. Vale lembrar que como bons modos você usar o instanceId para nomear seus campos e elementos, pois estarão no mesmo DOM e uma widget poderá confudir os elementos se não estiverem com o instanceId incrementado aos campos.

Outra coisa, se mudar o nome da variável, não esqueça de mudar o nome dos elementos nos seus arquivos .ftl de MyWidget.instance() para NOVO_NOME_VARIÁVEL.instance()

Ahh, não esqueça de mudar o id da sua widget para não ocorrer confusão por estarem no mesmo DOM.

Vale lembrar que é melhor escolher usar const e let ao invés de var.

Espero ter ajudado.

Abç..

Caro @Marcos, se entendi bem (tardiamente e após esperar uma ajuda preciosa como a sua), não devemos deixar o id do Div inicial de cada arquivo .ftl dentro da Widget, que o Studio põe como ‘default’, tipo MyWidget.

Ainda, se entendi bem, devemos renomear cada Edit e cada View para um nome nosso.
E, neste caso, se ainda entendi bem mesmo, se mudarmos o nome dos arquivo edit.ftl e view.ftl por algo nosso, também devemos alterar dentro do arquivo applicantion.info para que as entradas view.file e edit.file acompanhem justamente tais nomes.

Está correto?