Why am I getting, "Uncaught TypeError: getEnumerator is not a function"?

Why am I getting, "Uncaught TypeError: getEnumerator is not a function"?

在我的 Sharepoint 2010 Web 部件中,我有这个 Javascript:

function getListItemID(username, payeename, oList) {
    var arrayListEnum = oList.getEnumerator();

...由此调用:

function upsertPostTravelListItemTravelerInfo1() {
var clientContext = SP.ClientContext.get_current();
var oList =   
  clientContext.get_web().get_lists().getByTitle('PostTravelFormFields');

this.website = clientContext.get_web();
currentUser = website.get_currentUser();

var itemCreateInfo = new SP.ListItemCreationInformation();
this.oListItem = oList.addItem(itemCreateInfo);

var travelersEmail = $('traveleremail').val();

/* If this is an update, the call to getListItemID() will return a val; otherwise (an insert), get from newly instantiated ListItem.  */
listId = getListItemID(currentUser, travelersEmail, oList);

我从 获得了此代码的基础。

但是得到上面列出的错误 ("Uncaught TypeError: oList.getEnumerator is not a function");

一个回答说我需要添加这个:

<script type="text/javascript" src="/_layouts/15/sp.js" ></script>

...我将其从“15”更改为“14”,因为那是我们正在使用的 folder/version。

那不仅没有用,而且无法识别。然后我找到了一个线索here,就是添加这个:

$(document).ready(function () { ExecuteOrDelayUntilScriptLoaded(CustomAction, "sp.js"); });

...但这只是在已经显示的错误之前的错误,即“Uncaught ReferenceError: CustomAction is not defined

那么独家新闻是什么? getEnumerator() 或以其他方式检索我需要的 ID 值需要什么?

这是该方法的完整代码,以展示我要完成的工作以及如何完成:

function getListItemID(username, payeename, oList) {
  var arrayListEnum = oList.getEnumerator();

  while (arrayListEnum.moveNext()) {
     var listItem = arrayListEnum.get_current();

     if (listItem.get_item("ptli_formPreparedBy") === username &&
         listItem.get_item("ptli_TravelersEmail") === payeename &&
         listItem.get_item("ptli_formCompleted") == false) {
       return listItem.get_id();    
     }
   }
   return '';
}

更新

当我尝试这个时(第一行和第三行是新的):

<SharePoint:ScriptLinkID="ScriptLink1" Name="SP.js" runat="server" OnDemand="false" LoadAfterUI="true" Localizable="false"></SharePoint:ScriptLink>
<script type="text/javascript">
    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', sharePointReady);

...受到猫 here 的启发,我得到,“System.Web.HttpParseException 未被用户代码处理 Message=服务器标签格式不正确。"

就我个人而言,我认为 Sharepoint 的结构不是很好。但这是(正确的)题外话(没有双关语意)。

问题 1:您在列表而不是列表项集合上调用 getEnumerator

getEnumerator() (不在 List 对象上),并且仅在 运行ning clientContext.executeQueryAsync()

填充项目后

问题2:需要调用executeQueryAsync来填充列表项集合

使用 SharePoint JavaScript 客户端对象模型时,您的代码需要分为两部分:第一部分指定您想要获得的内容,并涉及将查询和命令加载到 SPClientContext 对象中;第二部分让您可以操纵对 SharePoint 的查询结果,并且 运行s 作为查询执行的异步回调。

  1. 创建您的上下文,指定您要访问的列表等。
  2. 运行 clientContext.executeQueryAsync()(其中 clientContext 是一个 SP.ClientContext 对象),并在成功或失败时将委托函数传递给 运行
  3. 在您的 "onSuccess" 委托函数中,您可以处理在步骤 1 中加载的命令的结果

问题 3:您将无法 return 直接从异步执行的函数中获取值

因为上面的第 3 步 运行 是异步的,你不能从中得到一个 return 值。任何依赖于您在步骤 3 中获得的结果的逻辑都需要使用函数委托和回调在执行链中向前移动。

问题四:列表项过滤效率低下

这实际上更像是一个设计缺陷,而不是一个停止显示的问题,而不是让你的代码 return 列表中的每个 项目,然后使用JavaScript 要枚举结果以查看您想要的项目是否在其中,您应该在 SharePoint 执行查询之前告知您想要的筛选器选项。然后它只会为您提供与您的查询相匹配的项目。

为此使用 CAML 查询; CAML(协作应用程序标记语言)是 SharePoint 广泛使用的一种基于 XML 的查询语言。有大量用于编写 CAML 查询的资源和工具,如果您已经创建了与您的查询相匹配的视图,您甚至可以从 SharePoint 列表视图 Web 部件中窃取 CAML 查询。

如何使用 JavaScript CSOM

查询 SharePoint 列表的示例

这是一个使用部分代码的示例:

/* 
   ExecuteOrDelayUntilScriptLoaded(yourcode,"sp.js") makes sure 
   your code doesn't run until SP.js (the SharePoint JavaScript CSOM) 
   has been loaded
*/
ExecuteOrDelayUntilScriptLoaded(function(){
    var payeename = $('traveleremail').val();
    var clientContext = SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getByTitle('PostTravelFormFields');

    /* Use a CAML query to filter your results */
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><Query><Where><Eq><FieldRef Name=\'ptli_TravelersEmail\' /><Value Type=\'Text\'>'+payeename+'</Value></Eq></Where></Query></View>');

    /* get the list item collection from the list */
    var oListItems = oList.getItems(camlQuery);

    /* tell SharePoint to load the list items */
    clientContext.load(oListItems);

    /* execute the query to get the loaded items */
    clientContext.executeQueryAsync(
        /* onSuccess Function */ 
        Function.createDelegate(this,function(){
            /* 
               now that the query has run, you can get an enumerator 
               from your list item collection 
            */
            var arrayListEnum = oListItems.getEnumerator();
            var ids = [];
            while(arrayListEnum.moveNext()){
                var listItem = arrayListItem.get_current();
                ids.push(listItem.get_id());
            }
            alert(ids.length > 0 ? "IDs of matching items: " + ids : "No matching items found!");
        }),
        /*onFailure Function*/ 
        Function.createDelegate(this,function(sender,args){
            alert("Whoops: " + args.get_message() + " " + args.get_stackTrace());
        })
    );
},"sp.js");

示例代码中的 CAML 查询仅在 ptli_TravelersEmail 列上进行过滤;您需要添加一些 <And> 元素来捕获您想要的其他两个过滤条件。

感谢 Thriggle,这终于对我有用了:

function setListItemID(username, payeename) {
    var clientContext = new SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getByTitle('PostTravelFormFields');

    /* Use a CAML query to filter your results */
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><Query><Where><Eq><FieldRef Name=\'ptli_TravelersEmail\' /><Value Type=\'Text\'>' + payeename + '</Value></Eq></Where></Query></View>');

    /* get the list item collection from the list */
    var oListItems = oList.getItems(camlQuery);

    /* tell SharePoint to load the list items */
    clientContext.load(oListItems);

    /* execute the query to get the loaded items */
    clientContext.executeQueryAsync(
        /* onSuccess Function */
        Function.createDelegate(this, function () {
            /* 
            now that the query has run, you can get an enumerator 
            from your list item collection 
            */
            var arrayListEnum = oListItems.getEnumerator();
            var ids = [];
            while (arrayListEnum.moveNext()) {
                var listItem = arrayListItem.get_current();
                ids.push(listItem.get_id());
            }
            if (ids.length > 0) {
                listId = ids[0];
            }
            else {
                listId = '';
            }
        }),
        /*onFailure Function*/
        Function.createDelegate(this, function (sender, args) {
            alert("Whoops: " + args.get_message() + " " + args.get_stackTrace());
        })
    );
}