2

ビューのクリック可能な要素の KnockoutJS バインディング ハンドラーを定義する次の TypeScript があります。

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 以降で非推奨になったため、別のアプローチを考えようとしています。

何か案は?

4

1 に答える 1

2

自分でクリックイベントを処理するのがより良いアプローチになると思います。

次に、Ajaxコールバックでテキストエリアを作成し、値を設定し、document.execCommand('copy')Clipboard.JSと同じように選択して呼び出します。これに似たもの(typescriptの代わりに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);
        }
      });
    });
  }
};

ここに同様の作業例があります(ajaxリクエストなし)

于 2016-05-19T16:55:37.443 に答える