문제

CSOM을 사용하여 특정보기에서 모든 표시된 필드를 검색하려고합니다.

필드 유형 및 필드 내부 이름을 알아야합니다.

나는 할 수 없다 :

var list = hostWebContext.get_web().get_lists().getByTitle('any list');
var view = list.get_views().getByTitle("All Items");
fieldsInView = view.get_viewFields();
context.load(fieldsInView);
context.executeQueryAsync(onListSuccess, OnListFail);
.

.get_viewfields ()는 필드 유형이 아닌 내부 이름 만 가져 오기 때문에. 그래서 내가 한 일은 먼저 목록에있는 모든 필드와 뷰의 필드를 얻고 필드를 반복 할 것입니다.목록에 있는지 확인하고 뷰에 있는지 확인하십시오. 즉, 아프다.

이것은 내가 지금까지 가지고있는 것입니다 :

function getList() {
    var hostWebContext = new SP.AppContextSite(context, decodeURIComponent(getQueryStringParameter("SPHostUrl")));


    var list = hostWebContext.get_web().get_lists().getByTitle('any list');
    var view = list.get_views().getByTitle("All Items");
    fields = list.get_fields();
    fieldsInView = view.get_viewFields();

    context.load(fields);
    context.load(fieldsInView);

    context.executeQueryAsync(onListSuccess, OnListFail);
}

function onListSuccess() {

    var fieldEnumerator = fields.getEnumerator();

    var fieldArray = new Array();

    while (fieldEnumerator.moveNext()) {
        var oField = fieldEnumerator.get_current();
        var fieldName = oField.get_internalName();



        if (!oField.get_hidden()) {
            var found = $.inArray(fieldName, fieldsInView) > -1;  // DOES NOT WORK!!


            var aField = {
                fieldName: fieldName,
                fieldType: oField.get_fieldTypeKind()
            };


            if (found) { fieldArray.push(aField); }
        }


    }

}
.

내 문제는 여기에 있습니다.

var found = $.inArray(fieldName, fieldsInView) > -1
.

변수 fieldsInView를 검사 할 때 값을 찾으면 실제로 같은 것으로 나타납니다. fieldSinView. $ 2_0. $ 1_0 [0] ....

다른 배열을 만들 수 있고 fieldsInView.getEnumerator () 명령을 사용하고 새 배열에 값을 추가 한 다음이를 처리합니다.하지만 이는 이중 처리와 같습니다.

더 나은 옵션이 있습니까?

도움이 되었습니까?

해결책

Two considerations here:

  1. The jQuery inArray function is implemented by calling the native Array indexOf function, if available, otherwise it uses a for loop to cycle through the array elements in search of a match.

  2. Your current inArray call doesn't work because, as you've already realized, fieldsInView is a SPFieldCollection, which is an object that internally is really just an array of fields, but the array isn't part of the public API (any variable whose name starts with the $ sign is not meant to be used directly by client code, although, being javascript, nothing can stops you from accessing them, but it's not guaranteed that a future upgrade won't break your code, if you choose to do that).

Performance-wise, I wouldn't really care of first looping through the fieldsInView collection with the enumerator that you get from the getEnumerator function, in order to build an array of pure strings (fields internal names). Then I would use this newly built array as the second argument to the inArray function call. I think that the performance hit would be unnoticeable (how many fields you have in your view? If it some tenths, looping through them would take a fraction of a second).

Otherwise, you can use the lodash library _some function, which enables you to enumerate an array and passing each item to a callback function (which is your search match condition), but returns as soon as it finds a passing value and does not iterate over the entire collection.

다른 팁

$.inArray function expects Array type to be passed, in your case fieldsInView variable is of SP.ViewFieldCollection type. So, in order to use fieldsInView in $.inArray it should be transformed into an Array, for example:

//Convert collection into array 
function collectionToArray(collection)
{
    var items = [];
    var e = collection.getEnumerator();
    while (e.moveNext()) {
       var item = e.get_current();
       items.push(item);                
    }
    return items;
}   

Example:

var context = SP.ClientContext.get_current();
var list = context.get_web().get_lists().getByTitle(listTitle);
var view = list.get_views().getByTitle(viewTitle);
var fieldsInView = view.get_viewFields();
context.load(fieldsInView);
var fields = list.get_fields();
context.load(fields);
context.executeQueryAsync(
    function(){
      var fieldsNames = collectionToArray(fieldsInView); //get field names array 

      var fieldEnumerator = fields.getEnumerator();
      var fieldArray = new Array();
      while (fieldEnumerator.moveNext()) {
        var field = fieldEnumerator.get_current();
        var fieldName = field.get_internalName();
        var found = $.inArray(fieldName, fieldsNames) > -1;
        //The remaining code is ommited for a clarity

      } 


    },
    function(sender,args){
          console.log(args.get_message());
    });

If you're enumerating through all the fields anyways why not just try something like this:

var internalNames = [];
var types = [];
var viewFieldEnum = viewFields.getEnumerator();
while (viewFieldEnum.moveNext()) {
  var currentViewField = viewFieldEnum.get_current();
  var allFieldsEnum = fields.getEnumerator();
  while (allFieldsEnum.moveNext()) {
    var currentField = allFieldsEmum.get_current();
    if (currentViewField === currentField.get_internalName()) {
      internalNames.push(currentField.get_internalName());
      types.push(currentField.get_fieldTypeKind());
    }
  }
}

It may not be the prettiest thing ever written, but would this work for you? Should get you the field internal names and their types.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 sharepoint.stackexchange
scroll top