2016-02-24 4 views
0

Как и в названии, я хочу получить имя типа содержимого элементов списка с помощью Javascript. быть конкретным: пользователь открывает «новую форму» в списке a, а с Javascript и CSR должно быть предупреждение о типе содержимого списка элементов списка в списке b. Для этого я пробовал следующее:SharePoint 2013 - Получить имена типов контента с помощью Javascript

var collListItem = null; 
var contentobject = null; 
var ctx = null; 
var oList = null; 
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({ 
    OnPostRender: function() { 
    $(document).ready(function() {ExecuteOrDelayUntilScriptLoaded(loadConstants, "sp.js")}); 
    } 
}); 
function loadConstants() { 
ctx = new SP.ClientContext.get_current(); 
var web = ctx.get_web(); 
ctx.load(web); 
var listcol = web.get_lists(); 
ctx.load(listcol); 
var oList = listcol.getByTitle('Aktionslisten'); 
var camlQuery = new SP.CamlQuery(); 
    camlQuery.set_viewXml('<View><Query><Where><Geq><FieldRef Name=\'ID\'/><Value Type=\'Number\'>1</Value></Geq></Where></Query></View>'); 
collListItem = oList.getItems(camlQuery); 
    ctx.load(collListItem); 
ctx.executeQueryAsync(Function.createDelegate(this, this.onSuccess), Function.createDelegate(this, this.onFail)); 
} 

function onSuccess(sender, args) { 
    var listInfo = ''; 
    var listEnumerator = collListItem.getEnumerator(); 
    while (listEnumerator.moveNext()){ 
     oList = listEnumerator.get_current(); 
     var ID = oList.get_id(); 
     contentobject = oList.get_contentType(); 
     ctx.load(contentobject); 
     ctx.executeQueryAsync(function(){ 
      var value = contentobject.get_name(); 
      alert("VAL: "+value); 
     },function(){alert("No Success");}); 


    } 
} 

function onFail(sender, args) { 
    console.log("Errorlog: "+ args.get_message()); 
} 

Но этот код просто дает мне тип содержимого последнего элемента несколько раз. Я думаю, что я, возможно, что-то не так с функцией «executeQuery»?

С наилучшими пожеланиями, Андре

Update (см комментарии ниже)

Новая попытка для кода, который также не работает:

var collListItem = null; 
var ctx = null; 
var oList = null; 
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({ 
    OnPostRender: function() { 
    $(document).ready(function() {ExecuteOrDelayUntilScriptLoaded(loadConstants, "sp.js")}); 
    } 
}); 
function loadConstants() { 
ctx = new SP.ClientContext.get_current(); 
var web = ctx.get_web(); 
ctx.load(web); 
var listcol = web.get_lists(); 
ctx.load(listcol); 
var oList = listcol.getByTitle('Aktionslisten'); 
var camlQuery = new SP.CamlQuery(); 
    camlQuery.set_viewXml('<View><Query><Where><Geq><FieldRef Name=\'ID\'/><Value Type=\'Number\'>1</Value></Geq></Where></Query></View>'); 
collListItem = oList.getItems(camlQuery); 
    ctx.load(collListItem); 
ctx.executeQueryAsync(Function.createDelegate(this, this.onSuccess), Function.createDelegate(this, this.onFail)); 
} 

function onSuccess(sender, args) { 
    var listInfo = ''; 
    var listEnumerator = collListItem.getEnumerator(); 
    while (listEnumerator.moveNext()){ 
     oList = listEnumerator.get_current(); 
     getcontenttypetitle(oList.get_contentType(), ctx); 
    } 
} 

function onFail(sender, args) { 
    console.log("Errorlog: "+ args.get_message()); 
} 

function getcontenttypetitle(contentobject,clientContext){ 
    this.object = contentobject; 
    clientContext.load(object); 
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onSuccess2), Function.createDelegate(this,this.onFail2)); 
} 

function onSuccess2 (sender,args){ 
alert("VAL: "+ this.object.get_name()); 
} 

function onFail2(sender,args){ 
    alert("fail"); 
} 

//$(":input[title='Aktionsliste']").find('option:contains(Teammeetings)').remove(); 
+0

Причина, почему он предупреждает те же самые, несколько раз, потому что, когда ваш обратный вызов 'executeQueryAsync' выполняется, любые переменные в замыкании относятся к фактическому переменным в этой области видимости , То есть, замыкание захватывает * variable * 'contentobject', а не его текущее значение при вызове' executeQueryAsync'. Поскольку это относится к переменной, ее значением обратного вызова является значение в конце цикла. Чтобы исправить это, вам нужно создать отдельное закрытие для каждого «contentobject». Чтобы узнать, как это делается, прочитайте этот ответ на вопрос об этой проблеме: http://stackoverflow.com/a/19324832/2407870 –

+0

Привет, спасибо за ваш быстрый ответ. Я прочитал статью и сделал новую попытку, которая снова повторяет ту же ошибку. Я отправил новый Кодекс в конце моего вопроса. То, что я думал/пытался: Я создал новую функцию «getcontenttypetitle». Эта функция получает текущий contentType элемента списка и clientContext. Я думал, что это решит проблему, поскольку я даю ей текущий контент, а не последний? Я полагаю, что проблема все еще существует из-за этого. Но если я не использую это ключевое слово, то как я могу получить доступ к переменной в «onSuccess2»? – Aquen

ответ

0

Причина, почему он предупреждает одно и то же много раз, потому что, когда выполняется обратный вызов executeQueryAsync, любые переменные в закрытии относятся к фактическим переменным в этой области. То есть, замыкание захватывает переменную contentobject, а не ее текущее значение при вызове executeQueryAsync. Поскольку это относится к переменной, ее значением обратного вызова является значение в конце цикла. Чтобы исправить это, вам нужно создать отдельное закрытие для каждого контент-объекта. Чтобы узнать, как это сделать, прочитайте этот ответ на вопрос об этой проблеме: https://stackoverflow.com/a/19324832/2407870.

Вы были ближе к своей предыдущей редакции. Вот часть из вашей первой версии, которую вам нужно изменить. (Обратите внимание на комментарии в коде.)

while (listEnumerator.moveNext()){ 
    oList = listEnumerator.get_current(); 
    var ID = oList.get_id(); 
    contentobject = oList.get_contentType(); 
    ctx.load(contentobject); 
    ctx.executeQueryAsync(
     // !! Here we use an IIFE (immediately invoked function expression) 
     // to create a new callback each time through the loop. 
     // We pass in the contentobject into our IIFE, 
     // which causes the closure to be around the variable 
     // inside the scope of our IIFE, 
     // instead of inside the scope of the function containing the while loop. 
     (function (contentobject) { 
      return function() { 
       var value = contentobject.get_name(); 
       alert("VAL: "+value); 
      }; 
     }(contentobject)), 
     function() { 
      alert("No Success"); 
     } 
    ); 
} 
+0

А, ок. теперь я получаю более четкое представление об объеме переменных. Спасибо! – Aquen