我有以下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开始被弃用,我试图想到另一种方法。
有什么想法吗?
答案 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请求)