Pergunta

Tenho um tipo de campo personalizado para o SharePoint 2010/2007, mas depois de migrar para o SharePoint 2013, encontrei um problema.
Aqui está o que defini para "RenderPattern" em fldtypes_myfield.xml

<RenderPattern Name="DisplayPattern">
<HTML><![CDATA[<script type="text/javascript" src="/_layouts/myfield/myjs.js"></script>]]></HTML>
<HTML><![CDATA[<img src="/_layouts/images/myfield/pic.png" onload="myfun()">]]></HTML>
</RenderPattern>

myfun() é definido em myjs.js, então quando pic.png for carregado, ele executará a função.Funciona bem na experiência do usuário de 2010/2007 e 2010 no SharePoint 2013.
Em 2013, na experiência do usuário de 2013, quando visualizo a lista que contém meu campo, ocorre o erro:

myfun is not defined  

Então, o motivo é óbvio, myjs.js não foi adicionado à página.(O link js está correto, copie o link para a barra de endereço e o navegador poderá exibi-lo)
Então, minha pergunta é: por que myjs.js não está registrado?
Alguma ideia?Desde já, obrigado.

Atualizar:
Não funciona na página "ListView", mas funciona na página "DisplayForm"."CAMLRendering" está definido como verdadeiro.Na página "ListView", se você verificar o campo com a ferramenta de desenvolvedor web, a marcação html dentro dela é:

<SCRIPT type=text/javascript src="/_layouts/myfield/myjs.js"></SCRIPT>  
<DIV><IMG src="/_layouts/images/myfield/pic.png" onload="myfun()"></DIV>  

O SharePoint 2013 proíbe o carregamento do js?

Foi útil?

Solução

Após a depuração, descobri que existe uma variável chamada "WPQ2ListData" que armazena o conteúdo dos dados da lista, seu formato é:

var WPQ2ListData = {
"Row": [{
    "ID": "1",
    "PermMask": "0x7fffffffffffffff",
    "FSObjType": "0",
    "Title": "A",
    "FileLeafRef": "1_.000",
    "Created_x0020_Date.ifnew": "1",
    "FileRef": "\u002ftest\u002fLists\u002fRatingList\u002f1_.000",
    "File_x0020_Type": "",
    "File_x0020_Type.mapapp": "",
    "HTML_x0020_File_x0020_Type.File_x0020_Type.mapcon": "",
    "HTML_x0020_File_x0020_Type.File_x0020_Type.mapico": "icgen.gif",
    "ContentTypeId": "0x01008AD43674D321D3428ACAFC1C3BD2971E",
    "MyField": "<script type=\"text/javascript\" src=\"/_layouts/myfield/myjs.js\"></script><img src=\"/_layouts/images/myfield/pic.png\" onload=\"myfun()\">"
}],
"FirstRow": 1,
"LastRow": 1,
"FilterLink": "?",
"ForceNoHierarchy": "1",
"HierarchyHasIndention": ""

}

Preste atenção em "MyField", pois contém o conteúdo que deve ser renderizado.
Na página, "WPQ2ListData" é usado em um só lugar:

ctx = new ContextInfo();  
//other assignments
ctx.ListData = WPQ2ListData;

Em seguida, "ctx" será passado para a função "RenderListView", que é responsável por renderizar a visualização da lista.Esta função é definida em "clienttemplates.js".Se você mergulhar nisso, descobrirá que ele chamará outra função chamada "SPClientRenderer.Render", nesta função irá gerar todo o conteúdo html para os dados da lista e inseri-lo em um td (talvez um div) como HTML interno.

var result = SPClientRenderer.RenderCore(renderCtx);  
if (result != null && result != '') {
    if (node.tagName == "DIV" || node.tagName == "TD") {  
        if (renderCtx.fHidden)  
            if (renderCtx.fHidden)  
        node.innerHTML = result;
    }else{
        //create div element, and insert result as innerHTML   
    }
}  

Preste atenção em "node.innerHTML=resultado", pois se algum conteúdo de string for inserido em um elemento como innerHTML e o conteúdo contiver código JavaScript, o código js não será executado.E é por isso que "myjs.js" não é adicionado à página! Acho que essa é uma das grandes diferenças na renderização da visualização de lista em 2010 e 2013. Em 2010, o HTML dos dados da lista é enviado diretamente para a página, enquanto é inserido na página dinamicamente em 2013.

Solução:
Na verdade, ainda existe um local que contém código js e pode executá-lo.Está "onload" em img.Então, por que não registramos nosso arquivo js aqui?E depois que myjs.js for carregado, deixe-o chamar myfun()!

var head = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '/_layouts/myfield/myjs.js';
script.onload = script.onreadystatechange = function() {
    myfun();
};
head.appendChild(script);  

E para melhor desempenho, não precisamos registrar myjs.js para cada linha, devemos verificar primeiro se ele existe.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a sharepoint.stackexchange
scroll top