2016-05-17 87 views
2

我已經爲運行搜索的單詞創建了一個taskpane插件,並將結果信息作爲列表顯示給用戶。 當用戶點擊列表中的一個項目時,我想選擇單詞範圍以向用戶顯示該項目的位置。 插件將允許用戶在該範圍上執行其他任務,例如更改字體顏色。如何在不同的Word.run上下文中使用範圍?

我能夠運行搜索,並使用下面的函數獲取範圍顯示:

function runSearch(textToFind) { 
    var items = []; 
    return Word.run(function(context) { 
    var options = Word.SearchOptions.newObject(context); 
    options.matchWildCards = false; 

    var rangesFind = context.document.body.search(textToFind, options); 
    context.load(rangesFind, 'text, font, style'); 
    return context.sync().then(function() { 
     for (var i = 0; i < rangesFind.items.length; i++) { 
     items.push(rangesFind.items[i]); 
     context.trackedObjects.add(rangesFind.items[i]); 
     } 
     return context.sync(); 
    }); 
    }) 
    .then(function() { 
    return items; 
    }); 
}; 

但是我有困難選擇在用戶點擊的範圍內。 我一直在使用範圍方面的嘗試:

function selectRange(range){ 
    range.select(); 
    return range.context.sync(); 
} 

或者使用範圍的新Word.run背景:

function selectRange(range){ 
    return Word.run(function(context) { 
    context.load(range); 
    return context.sync().then(function(){ 
     range.select(); 
     return context.sync(); 
    }); 
    }); 
} 

我所遇到的是涉及到創建的每個內容控制的潛在方法搜索結果,然後在新的上下文中重新加載selectRange函數中的所有內容控件,並找到匹配的控件,但是當我已經有範圍時,這似乎效率很低。

在不同的Word.run上下文中重用範圍的最佳方法是什麼?

回答

4

您不能在Word.run調用中使用對象。每當它被調用時,Word.run創建一個新的上下文,而原始對象綁定到它自己的上下文,從而產生不匹配。

話雖這麼說,你絕對可以,從Word.run內,添加你的願望context.trackedObjects.add(obj)的對象,他們將繼續擔任甚至Word.run執行完畢後,工作對象。通過「工作對象」,我的意思是他們的路徑不會失效(思考類似垃圾收集,但是對於遠程對象)。

一旦你有這樣的對象(和它上面看起來像你這樣做),你應該能夠調用

range.select(); 
range.context.sync().catch(...); 

如果它不爲你工作,你可以提供你的錯誤的例子得到些什麼?

爲了完整起見,我應該注意到,一旦您將對象添加到trackedObjects集合中,就可以有效地將這些對象的內存管理功能掌握在自己手中。這意味着如果你沒有正確地釋放內存,你的內存/範圍調整鏈就會減慢Word的運行速度。因此,一旦完成使用跟蹤對象,您應該撥打obj.context.trackedObjects.remove(obj),然後撥打obj.context.sync()。不要忘記最後一部分 - 如果你不做同步,你的移除被跟蹤對象的請求將不會被分派,並且你將繼續使用內存。

=======更新1 =======

湯姆,感謝提供錯誤信息。看起來這可能是API的Word實現中的一個錯誤 - 我會跟進,如果還有更多問題,有人可能會聯繫您。

從概念的角度來看,你是絕對正確的道路上 - 和下面的工作做在Excel中,例如:

var range; 
Excel.run(function (ctx) { 
    var sheet = ctx.workbook.worksheets.getActiveWorksheet(); 

    range = sheet.getRange("A5"); 
    range.values = [[5]]; 
    ctx.trackedObjects.add(range); 

    return ctx.sync(); 
}) 
.then(function(){ 
    setTimeout(function() { 
     range.select(); 
     range.context.trackedObjects.remove(range); 
     range.context.sync(); 
    }, 2000); 
}) 
.catch(function (error) { 
    showMessage("Error: " + error);   
}); 

=======更新2 ==== ===

事實證明,產品確實存在一個錯誤。不過,好消息是,使用僅支持JavaScript的修復程序很容易修復,事實上,我們將在接下來的幾周內更新CDN。

隨着修復,下面的代碼工作:

var paragraph; 
Word.run(function (ctx) { 
    var p = ctx.document.body.paragraphs.first; 
    paragraph = p.next; 
    ctx.trackedObjects.add(paragraph); 
    return ctx.sync(); 
}) 
.then(function(){ 
    setTimeout(function() { 
     paragraph.select(); 
     paragraph.context.trackedObjects.remove(paragraph); 
     paragraph.context.sync() 
      .then(function() { 
       console.log("Done"); 
      }) 
      .catch(handleError); 
    }, 2000); 
}) 
.catch(handleError); 

function handleError (error) { 
    console.log('Error: ' + JSON.stringify(error)); 
    if (error instanceof OfficeExtension.Error) { 
     console.log('Debug info: ' + JSON.stringify(error.debugInfo)); 
    } 
} 

想要更好的消息?在更新CDN之前,您可以使用下面的代碼「修補」JavaScript庫並使代碼在上面運行。您應該在Office.js已經加載後(即在您的Office.initialize函數中)以及在執行Word.run之前的一段時間運行此代碼。

var TrackedObjects = (function() { 
    function TrackedObjects(context) { 
     this._autoCleanupList = {}; 
     this.m_context = context; 
    } 
    TrackedObjects.prototype.add = function (param) { 
     var _this = this; 
     if (Array.isArray(param)) { 
      param.forEach(function (item) { return _this._addCommon(item, true); }); 
     } 
     else { 
      this._addCommon(param, true); 
     } 
    }; 
    TrackedObjects.prototype._autoAdd = function (object) { 
     this._addCommon(object, false); 
     this._autoCleanupList[object._objectPath.objectPathInfo.Id] = object; 
    }; 
    TrackedObjects.prototype._addCommon = function (object, isExplicitlyAdded) { 
     if (object[OfficeExtension.Constants.isTracked]) { 
      if (isExplicitlyAdded && this.m_context._autoCleanup) { 
       delete this._autoCleanupList[object._objectPath.objectPathInfo.Id]; 
      } 
      return; 
     } 
     var referenceId = object[OfficeExtension.Constants.referenceId]; 
     if (OfficeExtension.Utility.isNullOrEmptyString(referenceId) && object._KeepReference) { 
      object._KeepReference(); 
      OfficeExtension.ActionFactory.createInstantiateAction(this.m_context, object); 
      if (isExplicitlyAdded && this.m_context._autoCleanup) { 
       delete this._autoCleanupList[object._objectPath.objectPathInfo.Id]; 
      } 
      object[OfficeExtension.Constants.isTracked] = true; 
     } 
    }; 
    TrackedObjects.prototype.remove = function (param) { 
     var _this = this; 
     if (Array.isArray(param)) { 
      param.forEach(function (item) { return _this._removeCommon(item); }); 
     } 
     else { 
      this._removeCommon(param); 
     } 
    }; 
    TrackedObjects.prototype._removeCommon = function (object) { 
     var referenceId = object[OfficeExtension.Constants.referenceId]; 
     if (!OfficeExtension.Utility.isNullOrEmptyString(referenceId)) { 
      var rootObject = this.m_context._rootObject; 
      if (rootObject._RemoveReference) { 
       rootObject._RemoveReference(referenceId); 
      } 
      delete object[OfficeExtension.Constants.isTracked]; 
     } 
    }; 
    TrackedObjects.prototype._retrieveAndClearAutoCleanupList = function() { 
     var list = this._autoCleanupList; 
     this._autoCleanupList = {}; 
     return list; 
    }; 
    return TrackedObjects; 
}()); 
OfficeExtension.TrackedObjects = TrackedObjects; 

希望這有助於!

〜邁克爾Zlatkovsky,在Office擴展團隊開發,MSFT

+0

當我打電話'range.context.sync()'在上述我得到以下錯誤:'GeneralException:GeneralException { [功能]:, __proto__:{}, 代碼:「GeneralException 」, debuginfo軟:{ [功能]:, __proto__:{}, errorLocation: 「Document._GetObjectByReferenceId」 }, 消息: 「GeneralException」, 名: 「OfficeExtension.Error」, traceMessages:[] }' –

+0

Se我上面的兩個更新。 –

0

除了TrackedObjects修復需要更新以獲得信息搜索結果的範圍,而不是直接使用信息搜索結果的runSearch方法。

function runSearch(textToFind) { 
    var items = []; 
    return Word.run(function(context) { 
    var options = Word.SearchOptions.newObject(context); 
    options.matchWildCards = false; 

    var rangesFind = context.document.body.search(textToFind, options); 
    context.load(rangesFind); 
    return context.sync().then(function() { 
     for (var i = 0; i < rangesFind.items.length; i++) { 
     var range = rangesFind.items[i].getRange(); 
     context.load(range, 'text'); 
     items.push(range); 
     context.trackedObjects.add(items[items.length-1]); 
     } 
     return context.sync(); 
    }); 
    }) 
    .then(function() { 
    return items; 
    }); 
}; 
相關問題