Зарегистрируйте js для пользовательского типа поля в SharePoint 2013

sharepoint.stackexchange https://sharepoint.stackexchange.com//questions/54618

  •  10-12-2019
  •  | 
  •  

Вопрос

У меня есть пользовательский тип поля для SharePoint 2010/2007, но после перехода на SharePoint 2013 я столкнулся с проблемой.
Вот что я определил для "RenderPattern" в 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() определена в myjs.js, поэтому при загрузке pic.png она будет выполнять функцию.Это прекрасно работает в 2010/2007 и 2010 годах для пользователей SharePoint 2013.
В 2013 году, в разделе пользовательский опыт 2013, когда я просматриваю список, содержащий myfield, он выдает ошибку:

myfun is not defined  

Итак, причина очевидна, myjs.js не добавляется на страницу.(Ссылка js верна, скопируйте ссылку в адресную строку, и браузер сможет отобразить ее)
Итак, мой вопрос заключается в следующем: почему myjs.js не зарегистрирован?
Есть какие-нибудь идеи?Заранее благодарю.

Обновить:
Это не работает на странице "ListView", но работает на странице "DisplayForm".Для параметра "CAMLRendering" установлено значение true.На странице "ListView", если вы проверите это поле с помощью инструмента веб-разработчика, html-разметка внутри:

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

Запрещает ли SharePoint 2013 загрузку js?

Это было полезно?

Решение

После отладки я обнаружил, что существует переменная с именем "WPQ2ListData", которая хранит содержимое списка данных, ее формат:

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": ""

}

Обратите внимание на "MyField", в нем есть содержимое, которое должно быть отображено.
На странице "WPQ2ListData" используется в одном месте:

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

Затем "ctx" будет передан функции "RenderListView", которая отвечает за рендеринг представления списка.Эта функция определена в "clienttemplates.js".Если вы углубитесь в него, то обнаружите, что он вызовет другую функцию под названием "SPClientRenderer.Render", в этой функции она сгенерирует все html-содержимое для данных списка и вставит его в td (возможно, div) как innerHTML.

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   
    }
}  

Обратите внимание на "node.innerHTML = result", потому что если некоторое строковое содержимое вставлено в один элемент как innerHTML и содержимое содержит код JavaScript, js-код выполняться не будет.И вот почему "myjs.js" не добавляется на страницу! Я думаю, что это одно из больших различий при рендеринге списка в 2010 и 2013 годах, в 2010 году html-данные списка выводятся на страницу напрямую, в то время как в 2013 году они вставляются на страницу динамически.

Решение:
На самом деле, есть еще одно место, которое содержит js-код и может выполнить этот код.В img это "onload" (загрузка).Итак, почему бы нам не зарегистрировать наш js-файл здесь?И после загрузки myjs.js пусть он вызовет 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);  

И для повышения производительности нам не нужно регистрироваться myjs.js для каждой строки мы должны сначала проверить, существует ли она.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с sharepoint.stackexchange
scroll top