如何在不使用'async:false'且不使用回调的情况下等待ajax调用完成?

时间:2016-05-17 12:34:21

标签: ajax asynchronous knockout.js typescript clipboard.js

我有以下TypeScript为我的视图中的可点击元素定义KnockoutJS绑定处理程序:

module MyModule {
    export interface ICopyButtonParams {
        dataUrl: string;
    }

    ko.bindingHandlers.copyButton = {
        init: (element: HTMLElement, valueAccessor: () => ICopyButtonParams) => {
            var options: any = ko.utils.unwrapObservable(valueAccessor());
            if (!options.dataUrl) {
                return;
            }

            new Clipboard(element, {
                text: () => {
                    var clipboardData: string;

                    $.ajax({
                        url: options.dataUrl,
                        type: "GET",
                        contentType: "application/json",
                        cache: false,
                        async: false,
                        success: (result: SubmitResult) => {
                            clipboardData = result.Data;
                        }
                    });

                    return clipboardData;
                }
            });
        }
    };
}

此绑定处理程序的作用是将可单击元素转换为Clipboard.JS启用的元素,该元素在单击时将字符串存储在剪贴板中。在我的例子中,我想利用Clipboard.JS的动态文本功能,你可以将一个函数传递给Clipboard构造函数,该构造函数返回你想要存储在剪贴板中的文本。在这个函数中,我想调用一个返回要存储的文本的API。

由于这种体系结构的性质,我无法使用带有成功回调的标准ajax调用,因为这意味着剪贴板文本不会及时得到解决。

作为一种权宜之计,你会在我的代码中注意到我使我的ajax调用异步(糟糕,我知道)。由于'async'标志从JQuery 1.8开始被弃用,我试图想到另一种方法。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我认为更好的approuch将是您自己处理点击事件。

然后在你的ajax回调中创建一个textarea,设置值,选择并调用document.execCommand('copy')作为Clipboard.JS。类似的东西(抱歉javascript而不是打字稿)

ko.bindingHandlers.copyButton = {
  init: function(element, valueAccessor) {
    var url = ko.utils.unwrapObservable(valueAccessor());

    $(element).click(function() {
      $.ajax({
        url: url,
        type: "GET",
        contentType: "application/json",
        cache: false,
        async: false,
        success: function(result) {
          var ta = document.createElement('textarea');
          document.body.appendChild(ta);
          ta.value = result;
          ta.select();
          var r = document.createRange();
          r.selectNode(ta);
          document.getSelection().addRange(r);
          document.execCommand('copy');
          document.body.removeChild(ta);
        }
      });
    });
  }
};

我有一个类似的工作示例here(没有ajax请求)