Почему ContentControl.insertOoxml (original_content_control_ooxml) создает новые невидимые элементы управления контентом? - PullRequest
0 голосов
/ 05 июля 2019

Я хочу иметь возможность скрывать / показывать содержимое некоторых элементов управления контентом. Для этого я получаю ooxml контента, сохраняю и загружаю его с помощью customXmlParts и insertOoxml() back.

В настоящее время я могу прятаться и скрываться один раз. Со второй попытки скрытия, context.document.contentControls.getByTitle() дает мне вдвое больше элементов управления контентом, которые я вижу на экране. Половина идентификаторов новые. Когда я пытаюсь getOoxml() из них, система выдает ошибку с errorLocation из ContentControlCollection.getItem.

Я обещал Office 2013 apis следующим образом:

function cxpAddCustomXmlPartAsync(xml): 
  Promise<Office.AsyncResult<Office.CustomXmlPart>>{
  return new Promise((resolve)=>{
    Office.context.document.customXmlParts.addAsync(xml, (asyncResult)=>{
      resolve(asyncResult);
    })
  });
}

function cxpGetCustomXmlPartByIdAsync(id): 
  Promise<Office.AsyncResult<Office.CustomXmlPart>> {
  return new Promise((resolve)=>{
    Office.context.document.customXmlParts.getByIdAsync(id, 
      (result: Office.AsyncResult<Office.CustomXmlPart>)=>{
        resolve(result)
      })
  });
}

function cxpDeleteXmlPartAsync(part:Office.CustomXmlPart){
  return new Promise((resolve)=>{
    part.deleteAsync((result: Office.AsyncResult<void>)=>{
      resolve(result)
    });
  });
}

function cxpGetXmlAsync(part: Office.CustomXmlPart):
  Promise<Office.AsyncResult<string>> {
  return new Promise((resolve)=>{
    part.getXmlAsync((result)=>{
      resolve(result);
    });
  });
}

И следующая функция пытается скрыть / показать дважды. На второй итерации я получаю ошибку в строке с //*.

const customXmlIds = {};
export async function run() {
  return Word.run(async context => {
    for (let iteration=0;iteration<2;iteration++){
      // get a list of all content controls with title "My Title"
      let ccs = context.document.contentControls.getByTitle("My Title"); 
      ccs.load("id");
      await context.sync();
      write(JSON.stringify(ccs));

      // save contents of all the matching content controls
      for(let i=0; i <ccs.items.length; i++){
        const ooxmlObj = ccs.items[i].getOoxml(); // *
        await context.sync();

        const ooxml = ooxmlObj.value; 
        ccs.items[i].insertText("-", "Replace");
        const result = await cxpAddCustomXmlPartAsync(ooxml);
        customXmlIds[ccs.items[i].id] = result.value.id
        await context.sync()
      }


      // get a list of all content controls with title "My Title"
      ccs = context.document.contentControls.getByTitle("My Title");
      ccs.load("id");
      await context.sync();

      // load back content control data
      for(let i=0; i <ccs.items.length; i++){
        const xmlPartId = customXmlIds[ccs.items[i].id];
        const partResult = await cxpGetCustomXmlPartByIdAsync(xmlPartId);
        const xmlResult = await cxpGetXmlAsync(partResult.value);
        ccs.items[i].insertOoxml(xmlResult.value,"Replace");
        write(JSON.stringify(xmlResult))
        await context.sync();
        const deleteResult = await cxpDeleteXmlPartAsync(partResult.value);
        delete customXmlIds[xmlPartId];
      }
  }
  });
}

1 Ответ

1 голос
/ 10 июля 2019

Это забавный случай, и в некоторой степени вы описываете его дизайн и не были должным образом обработаны в вашем коде. На самом деле, я сомневаюсь, что это то, что вы хотите сделать. Позволь мне объяснить.

Корень проблемы в том, что, выполнив ccs.items [i] .getOoxml (), вы фактически получаете OOXML элемента управления содержимым, включая фактический элемент управления содержимым. вот почему, когда вы сохраняете, а затем заменяете содержимое cc тем OOXML, вы фактически вставляете элемент управления содержимым в элемент управления содержимым, поэтому каждый раз вы удваиваете размер элементов управления содержимым! :) Надеюсь, это не смущает ...

Я думаю, что вы действительно хотите, чтобы OOXML-ize - это то, что находится внутри управления контентом, верно? На основании вашего примера кода я предполагаю, что скрытие в этом контексте означает не весь элемент управления содержимым, а вместо этого вам нужен пустой элемент управления содержимым (с «-»), правильно?

Если это так, вам нужно получить OOXML «контента» элемента управления контентом. вот как ты это делаешь:

 const ooxmlObj = ccs.items[i]
        .getRange("start")
        .expandTo(ccs.items[i].getRange("end"))
        .getOoxml(); 

эта простая инструкция даст вам только внутреннюю часть управления контентом, то есть OOXML, который вам нужно сохранить, а затем заменить.

Пожалуйста, ознакомьтесь с рабочим образцом здесь (scriptlab) https://gist.github.com/JuaneloJuanelo/4a78ab47b7df9594bc7d097842166cbf

также я не уверен, почему вы сохраняете это как XML-часть ... я использовал массив в моем образце, затем вы можете использовать объект настроек для сохранения массива. до вас, где вы хотите хранить временные OOXMLs.

Удачного кодирования!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...