首页 > 解决方案 > ContentControl 操作减慢 Word Online

问题描述

预期行为

Word Online 是可用的,并且在编辑 ContentControls 时不会崩溃或急剧变慢。

当前行为

当通过 contentControl.insertHtml("mytext", "Replace") 将 HTML 插入到 ContentControl 中时,每次调用都需要更多时间。我尝试使用 clear() 函数并在不替换的情况下插入,但这导致了同样的问题。在尝试之后,我认为我缩小了清除 ContentControl 的范围,但经过进一步调查,编辑 ContentControl 的每个操作(替换、清除、插入)都会变得更糟。执行一项操作可能需要几分钟。经过几次测试后,单击 ContentControl 并按我的键盘上的任何键后,文档完全中断。我尝试清除缓存并在私人浏览器选项卡中打开文档,但没有任何效果。

我会附上我的文件。

测试文档.docx

重现步骤

我在 VisualStudio 中创建了一个新的 Word Web 加载项,并创建了一个最小示例来重现该问题。

主页.js:

    "use strict";

    var messageBanner;

    // Die Initialisierungsfunktion muss bei jedem Laden einer neuen Seite ausgeführt werden.
    Office.initialize = function (reason) {
        $(document).ready(function () {
            $('#insert-button').click(insert);
            $('#clear-button').click(clear);
            $('#replace-button').click(replace);
            loadCc();
        });
    };

    var cc;

    function loadCc() {
        Word.run(ctx => {
            let ccs = ctx.document.body.contentControls;

            ctx.load(ccs);
            
            return ctx.sync().then(function () {
                console.log(ccs.items.length);
                cc = ccs.items[0];
            });
        });
    }


    let string = "a";

    function clear() {
        if (cc) {
            let start = new Date().getTime();
            cc.clear();
            cc.context.sync().then(() => {
                let clear = new Date().getTime();
                console.log("Clear took: " + (clear - start));
            });
        }
    }

    function insert() {
        if (cc) {
            //cc.insertHtml(string, "Replace");
            let start = new Date().getTime();

            cc.insertHtml(string, "Start");
            cc.context.sync().then(() => {
                let insert = new Date().getTime();
                console.log("Insert took: " + (insert - start));
            });
        }
    }

    function replace() {
        if (cc) {
            let start = new Date().getTime();
   
            cc.insertHtml(string, "Replace");
            cc.untrack();
            cc.context.sync().then(() => {
                let insert = new Date().getTime();
                console.log("Replace took: " + (insert - start));
            });
        }
    }

    //$$(Helper function for treating errors, $loc_script_taskpane_home_js_comment34$)$$
    function errorHandler(error) {
        // $$(Always be sure to catch any accumulated errors that bubble up from the Word.run execution., $loc_script_taskpane_home_js_comment35$)$$
        showNotification("Fehler:", error);
        console.log("Error: " + error);
        if (error instanceof OfficeExtension.Error) {
            console.log("Debug info: " + JSON.stringify(error.debugInfo));
        }
    }

    // Eine Hilfsfunktion zum Anzeigen von Benachrichtigungen.
    function showNotification(header, content) {
        $("#notification-header").text(header);
        $("#notification-body").text(content);
        messageBanner.showBanner();
        messageBanner.toggleExpansion();
    }
})();

主页.html

<html>
<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <title>Word Add-In with Commands Sample</title>

    <script src="Scripts/jquery-3.5.0.js" type="text/javascript"></script>
    <script src="Scripts/MessageBanner.js" type="text/javascript"></script>
    <script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>



    <script src="Home.js" type="text/javascript"></script>
    <link href="Home.css" rel="stylesheet" type="text/css" />
    <link href="../Content/Button.css" rel="stylesheet" type="text/css" />
    <link href="../Content/MessageBanner.css" rel="stylesheet" type="text/css" />



    <link rel="stylesheet" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/9.6.0/css/fabric.min.css">


<body class="ms-Fabric" dir="ltr">
    <div id="content-main">
        <div class="padding">
            <button class="Button Button--primary" id="insert-button">
                Insert
            </button>
            <button class="Button Button--primary" id="clear-button">
                Clear
            </button>
            <button class="Button Button--primary" id="replace-button">
                Replace
            </button>
        </div>
    </div>

    <div class="MessageBanner" id="notification-popup">
        <div class="MessageBanner-content">
            <div class="MessageBanner-text">
                <div class="MessageBanner-clipper">
                    <div class="ms-font-m-plus ms-fontWeight-semibold" id="notification-header"></div>
                    <div class="ms-font-m ms-fontWeight-semilight" id="notification-body"></div>
                </div>
            </div>
            <button class="MessageBanner-expand" style="display:none"><i class="ms-Icon ms-Icon--chevronsDown"></i> </button>
            <div class="MessageBanner-action"></div>
        </div>
        <button class="MessageBanner-close"> <i class="ms-Icon ms-Icon--ChromeClose"></i> </button>
    </div>
</body>
</html>

标签: javascriptms-wordoffice365office-jsoffice-addins

解决方案


要解决此问题,必须使用异步方法并等待context.sync()-Calls 而不是使用 Promisesthen()回调。

固定代码:


(function () {
    "use strict";

    var messageBanner;

    // Die Initialisierungsfunktion muss bei jedem Laden einer neuen Seite ausgeführt werden.
    Office.initialize = function (reason) {
        $(document).ready(function () {
            $('#insert-button').click(insert);
            $('#clear-button').click(clear);
            $('#replace-button').click(replace);
            loadCc();
        });
    };

    var cc;

    async function loadCc() {
        await Word.run(async ctx => {
            let ccs = ctx.document.body.contentControls;

            ctx.load(ccs);
            
            await ctx.sync();

            console.log(ccs.items.length);
            cc = ccs.items[0];
        });
    }


    let string = "a";

    async function clear() {
        if (cc) {
            let start = new Date().getTime();
            cc.clear();
            await cc.context.sync();
            let clear = new Date().getTime();
            console.log("Clear took: " + (clear - start));
        }
    }

    async function insert() {
        if (cc) {
            //cc.insertHtml(string, "Replace");
            let start = new Date().getTime();

            cc.insertHtml(string, "Start");
            await cc.context.sync();

            let insert = new Date().getTime();
            console.log("Insert took: " + (insert - start));
        }
    }

    async function replace() {
        if (cc) {
            let start = new Date().getTime();
   
            cc.insertHtml(string, "Replace");
            await cc.context.sync();

            let insert = new Date().getTime();
            console.log("Replace took: " + (insert - start));
        }
    }

    //$$(Helper function for treating errors, $loc_script_taskpane_home_js_comment34$)$$
    function errorHandler(error) {
        // $$(Always be sure to catch any accumulated errors that bubble up from the Word.run execution., $loc_script_taskpane_home_js_comment35$)$$
        showNotification("Fehler:", error);
        console.log("Error: " + error);
        if (error instanceof OfficeExtension.Error) {
            console.log("Debug info: " + JSON.stringify(error.debugInfo));
        }
    }

    // Eine Hilfsfunktion zum Anzeigen von Benachrichtigungen.
    function showNotification(header, content) {
        $("#notification-header").text(header);
        $("#notification-body").text(content);
        messageBanner.showBanner();
        messageBanner.toggleExpansion();
    }
})();


推荐阅读