Word Online加载项:在多个上下文中使用对象 [英] Word Online Add-In: Using objects across multiple contexts

查看:71
本文介绍了Word Online加载项:在多个上下文中使用对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个插件,将一个段落拆分成多个句子,然后说出来,并在阅读时突出显示这些句子.在大多数情况下,我可以进行此工作,但是当我要突出显示当前正在阅读的句子时,问题就来了.

I'm attempting to make an add-in, whereby a paragraph is split into sentences and then spoken, with the sentences being highlighted as they are read. For the most part, I have this working but the issue comes when I want to highlight the sentences currently being read.

我有一个功能,可以根据用户光标所在的位置将段落分为句子:

I have a function which splits the paragraph into sentences, based on where the users cursor is:

function selectionTest() {
    Word.run(function (context) {
        originalRange = context.document.getSelection();
        var paragraphs = originalRange.paragraphs;

        context.load(paragraphs, 'text');
        context.load(originalRange, 'text');

        return context.sync().then(function () {
            //Range should only be present in a single paragraph, rather than spanning multiple
            if (paragraphs.items.length === 1) {
                var paragraph = paragraphs.items[0];

                var ranges = paragraph.getTextRanges(['.'], true);

                context.load(ranges, 'text');
                return context.sync(ranges);
            }
        }).then(function (sentences) {
            ...

我想突出显示"originalRange"对象上的文本,以便突出显示正确的句子,如下所示:

I want to base highlighting the text on the 'originalRange' object, so that the correct sentences are highlighted, like the following:

function highlightSentence(id, colour) {
    Word.run(function (context) {
        var paragraphs = originalRange.paragraphs;

        context.load(paragraphs, 'text');
        context.load(originalRange, 'text');
        ...

但是这会产生错误,因为在多个上下文中使用了"originalRange".我有办法在多个上下文或其他解决方案中使用"originalRange"吗?

But this produces an error as 'originalRange' is being used over multiple contexts. Is there a way for me to use 'originalRange' over multiple contexts or another solution?

更新:

我尝试在函数中再次获取段落的句子,使用'context.trackedObjects.add'作为原始范围.尝试从中获取"paragraphs"属性时,这会导致相同的错误.

I attempted to get the sentences of the paragraphs again within the function, using 'context.trackedObjects.add' for the original range. This caused the same error when attempting to get the 'paragraphs' property from it.

我意识到,我可能需要的只是这些段落的句子,而不是使用原始范围再次获取这些句子.相反,我实现了另一种解决方案:

I realised that all I potentially needed was the sentences of the paragraphs, instead of using the original range to get the sentences again. Instead, I implemented a different solution:

function highlightSentence(id, colour) {
    Word.run(function (context) {
        context.trackedObjects.add(gSentences);

        return context.sync().then(function () {
            gSentences.items[id].font.highlightColor = colour;
        }).then(context.sync);

    }).then(function(){   
        gSentences.context.trackedObjects.remove(gSentences);
        gSentences.context.sync();
    }).catch(function(error) {
        console.log(error.message);
    });
}

但是,我现在收到以下错误: 对象路径'_reference()'不适用于您要执行的操作.如果您正在多个\"context.sync \"调用中使用该对象,并且在\的顺序执行之外使用该对象".run \"批处理,请使用\"context.trackedObjects.add()\"和\"context.trackedObjects.remove()\"方法来管理对象的生存期."

However, I now get the following error: "The object path '_reference()' isn't working for what you're trying to do. If you're using the object across multiple \"context.sync\" calls and outside the sequential execution of a \".run\" batch, please use the \"context.trackedObjects.add()\" and \"context.trackedObjects.remove()\" methods to manage the object's lifetime."

更新:

我设法解决了上述问题.但是,现在,在突出显示功能期间,由于尚未在上下文中加载"gSentences"变量,因此其属性(例如字体")不可用,因此我无法更改突出显示颜色.如果我尝试在上下文中加载它,则会出现原始错误无法跨上下文使用对象".我现在不知道该怎么办.

I managed to solve the issue above. However, now, during the highlight function, since the 'gSentences' variable has not been loaded within the context, its properties such as 'font' are not available, so I am unable to change the highlight colour. If I attempt to load it in the context, the original error of 'cannot use objects across contexts' appears. I'm not sure what to do at this point.

更新:

这是我用来检索段落中相同位置或光标之后的句子的方法.这些句子被推送到要说的数组中.我发现我不得不在很多情况下使用回调才能做到这一点.

This is what I use to retrieve sentences in a paragraph that are either the same position or after the cursor. These sentences are pushed to an array to be spoken. I found that I had to mess around a lot with callbacks to do this.

function selectionTest() {
    Word.run(function (context) {
        var range = context.document.getSelection();
        var paragraphs = range.paragraphs;

        context.load(paragraphs, 'text');

        return context.sync().then(function () {
            if (paragraphs.items.length === 1) {
                var paragraph = paragraphs.items[0];

                gSentences = paragraph.getTextRanges(['.'], true);

                context.load(gSentences);
                return context.sync();
            }
        }).then(function () {
            if (gSentences.items) {
                var sentencesResult = '';
                var callbacklist = [];

                currentSentence = 0;
                sentencesToSpeak = [];

                function isSentenceinRange(idx, fn) {
                    var rangeLoc = gSentences.items[idx].compareLocationWith(range);

                    return context.sync().then(function () {
                        if (rangeLoc.value === Word.LocationRelation.contains || rangeLoc.value === Word.InsertLocation.after) {
                            return fn(gSentences.items[idx].text);
                        }

                        return fn('');
                    });
                }

                for (var i = 0; i < gSentences.items.length; i++) {
                    callbacklist.push(
                        (function (i) {
                            return function () {
                                isSentenceinRange(i, function (result) {
                                    if (result) {
                                        sentencesToSpeak.push({ id: i, text: result });

                                        if (i === gSentences.items.length - 1) {
                                            sentencesFinialised();
                                        }
                                    }
                                });
                            }
                        })(i)
                    );
                }

                for (var callback in callbacklist) {
                    callbacklist[callback].call(this);
                }

            }
        });
    }).catch(function (error) {
        console.log(error.message);
    });
}

我想在说出句子时突出显示句子,这就是下一个函数将要使用的功能(在音频元素的onend事件监听器上调用)

I wanted to highlight the sentences while they were being spoken, which is what the next function would be used to do (called on the onend event listener of audio element)

 function highlightSentenceTest(id, colour) {
    Word.run(function (context) {
        context.trackedObjects.add(gSentences);
        //Causes error, but need to load to get access?
        context.load(gSentences);

        return context.sync().then(function () {
            gSentences.items[id].font.highlightColor = colour;

        }).then(context.sync)
    }).catch(function(error) {
        console.log(error.message);
    });
}

推荐答案

很好的问题!听起来很像我在这里回答的内容:

Very good question! It sounds a lot like something that I answered here: How can a range be used across different Word.run contexts?

如果这没有帮助,请在您的情况下发表评论,我会尽力提供帮助.

If that doesn't help, please leave a comment with what is different about your scenario, and I can try to help.

〜MSFT Office可扩展性团队的开发人员Michael Zlatkovsky

~ Michael Zlatkovsky, developer on Office Extensibility team, MSFT

P.S .:请用 office-js 标记您的问题,以确保我们(产品组和社区)都能看到它们.

P.S.: Please tag your questions with office-js to make sure that we (the product group, and the community as well) see them.


根据已更新的问题/代码进行更新:

说实话,目前还不清楚您的回调函数在做什么...但是让我给您一些一般性的指导,看看是否有帮助:

Truthfully, it is somewhat unclear what your callbacks are doing... but let me give you some general guidance, and see if that helps:

  • 对于在Word.run(function(ctx) { ... })期间创建的任何对象,该对象将在Word.run完成执行后立即变为无效.我并不是从JS垃圾收集的意义上讲它,而是从不再绑定到文档"的意义上讲.因此,即使您在Word.run内创建了一个试图捕获范围的回调函数,它本身也不会起作用.

  • For any object created during a Word.run(function(ctx) { ... }), the object will become invalid as soon as Word.run is done executing. I don't mean it in a JS garbage-collection sense, but rather in the "will-no-longer-be-bound-to-the-document" sense. So even if you create a callback function within Word.run trying to capture scope, that won't work in of itself.

当您确实希望在两次执行之间保留一个对象(或者说,让它保留在Excel.run之后)时,必须将其添加到ctx.trackedObjects中.您需要在.run内执行此操作,否则将为时已晚.

When you do want to preserve an object between executions (or rather, let it live beyond the Excel.run), you must add it to ctx.trackedObjects. You need to do that within the .run, or else it'll be too late.

要在此之后使用该对象,您将不能再使用Word.run,而是直接使用上下文.

To use the object thereafter, you can no longer use Word.run, but instead use the context directly.

savedObject.doSomething(); //或savedObject.load("someProperty"); savedObject.context.sync() .then(...)//可选 .catch(...);

savedObject.doSomething(); // or savedObject.load("someProperty"); savedObject.context.sync() .then(...) // optional .catch(...);

顺便说一句:我们正在积极努力简化此模式,敬请期待...

目前,您需要使用

For now, you need to use the TrackedObjects workaround (extra code) described on How can a range be used across different Word.run contexts?, though we should be updating Office.js fairly soon with the fix.

这有助于您不受阻碍吗?

Does that help you get unblocked?

〜迈克尔

这篇关于Word Online加载项:在多个上下文中使用对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆