Sharepoint:如何使用JSOM轻松获取相关的子项

时间:2014-09-13 16:01:57

标签: sharepoint sharepoint-2010 sharepoint-2013 sharepoint-clientobject

假设我有2个列表:团队和员工。每个团队都有许多员工:

Teams
  ID
  Name

Employees
  ID
  Name
  TeamID (foreign key of Teams)

是否可以在SharePoint JSOM中编写查询,以便我可以沿着以下行执行某些操作(在查询执行/加载之后):

var employeesListItems = teamListItem.get_item("Employees")

SharePoint对象模型是否以任何方式支持此操作?

澄清:我的意图是尽可能多地重用ClientObject。我了解我可以查询所有员工和所有团队,为每个团队创建一系列自定义对象,然后对员工进行迭代并将其推送到员工"员工"相关Team对象的字段。我想避免这样做。

2 个答案:

答案 0 :(得分:5)

即使SharePoint CAML支持List Joins and Projections,在这种情况下,我建议您采用不同的方法。

以下示例演示了如何使用单个请求检索父/子项:

function getItemWithDetails(parentListTitle,childListTitle,lookupFieldName,lookupFieldValue,success,error)
{ 
   var ctx = SP.ClientContext.get_current();
   var web = ctx.get_web();
   var lists = web.get_lists();
   var parentList = lists.getByTitle(parentListTitle);
   var parentItem = parentList.getItemById(lookupFieldValue);
   var childList = lists.getByTitle(childListTitle);
   var childItems = childList.getItems(createLookupQuery(lookupFieldName,lookupFieldValue));

   ctx.load(parentItem);
   ctx.load(childItems);
   ctx.executeQueryAsync(
     function() {
       success(parentItem,childItems);  
     },
     error
   );
}

function createLookupQuery(lookFieldName,lookupFieldValue)
{
   var queryText = 
"<View>" +
  "<Query>" +
    "<Where>"  + 
       "<Eq>" +
           "<FieldRef Name='{0}' LookupId='TRUE'/>" +
           "<Value Type='Lookup'>{1}</Value>" +
        "</Eq>" +
    "</Where>" +
 "</Query>" +
"</View>";   
    var qry = new SP.CamlQuery();
    qry.set_viewXml(String.format(queryText,lookFieldName,lookupFieldValue));
    return qry;
}

<强>用法

var parentListTitle = 'Teams';
var childListTitle = 'Employees' 
var lookupFieldValue = 1;
var lookupFieldName = 'Team';

getItemWithDetails(parentListTitle,childListTitle,lookupFieldName,lookupFieldValue,
  function(teamItem,employeeItems){
     //print parent item 
     console.log(teamItem.get_item('Title'));
     //print child items
     for(var i = 0; i < employeeItems.get_count(); i++){
        var employeeItem = employeeItems.getItemAtIndex(i);
        console.log(employeeItem.get_item('Title'));
     }
  },
  function(sender,args){
      console.log(args.get_message());
  });

另一种选择是利用List Joins and Projections。以下示例演示了如何使用投影团队项目检索员工列表项

function getListItems(listTitle,joinListTitle,joinFieldName,projectedFields,success,error)
{ 
   var ctx = SP.ClientContext.get_current();
   var web = ctx.get_web();
   var list =  web.get_lists().getByTitle(listTitle);
   var items = list.getItems(createJoinQuery(joinListTitle,joinFieldName,projectedFields));

   ctx.load(items);
   ctx.executeQueryAsync(
     function() {
       success(items);  
     },
     error
   );
}


function createJoinQuery(joinListTitle,joinFieldName,projectedFields)
{
   var queryText = 
"<View>" +
  "<Query/>" +
  "<ProjectedFields>";
  for(var idx in projectedFields) {
    queryText += String.format("<Field Name='{0}_{1}' Type='Lookup' List='{0}' ShowField='{1}' />",joinListTitle,projectedFields[idx]);
  }
  queryText +=
  "</ProjectedFields>" +
  "<Joins>" +
      "<Join Type='INNER' ListAlias='{0}'>" +
        "<Eq>" +
          "<FieldRef Name='{1}' RefType='Id'/>" +
          "<FieldRef List='{0}' Name='ID'/>" +
          "</Eq>" +
        "</Join>" +
    "</Joins>" +
"</View>";   
    var qry = new SP.CamlQuery();
    qry.set_viewXml(String.format(queryText,joinListTitle,joinFieldName));
    return qry;
}

<强>用法

var listTitle = 'Employees';
var joinListTitle = 'Teams' 
var joinFieldName = 'Team';
var projectedFields = ['ID','Title'];

getListItems(listTitle,joinListTitle,joinFieldName,projectedFields,
  function(employeeItems){
     //print items
     for(var i = 0; i < employeeItems.get_count(); i++){
        var employeeItem = employeeItems.getItemAtIndex(i);
        var employeeName = employeeItem.get_item('Title');
        var teamName = employeeItem.get_item('Teams_Title').get_lookupValue();
        console.log(employeeName + ',' + teamName);
     }
  },
  function(sender,args){
      console.log(args.get_message());
  });

答案 1 :(得分:0)

由于查找配置,可能无法达到您想要的效果。但你可以做到以下几点:

var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var lists = web.get_lists();
var teams = lists.getByTitle("Teams");
var employees = lists.getByTitle("Employees");

//just get the first item
var employee = employees.getItemById(1);
ctx.load(employee)
ctx.executeQueryAsync(function() {
    var team = employee.get_item("TeamID");
    // both the id and the  value of the lookup field
    var lookupId = team.get_lookupId();
    var lookupValue = team.get_lookupValue();
    // let's grab all the fields
    var fullTeam = teams.getItemById(lookupId)
    ctx.load(fullTeam)
    ctx.executeQueryAsync({
        var name = fullTeam.get_item("Name");
        alert("We can get the Name field of the lookup field: " + name);
    }); 
});

我想,它与你真正想要达到的目标有点相反,但仍然会以这种方式利用CSOM。