我有一个成功运行的jQuery UI插件。我想将其转换为jQuery UI Widget Factory。我当前的小部件允许我在所有选定元素上应用一个初始化。
我在我的this.each声明之前这样做。效果很好。
我这样调用我当前的插件:
$("input[title *= 'Cost Center Name']").simpleDialogListSP({spListName : "Cost Centers",
dialogTitle : "Cost Centers"
});
我有多个输入框,标题为“成本中心名称X”。我的插件熄灭并抓取所有选定输入框中使用的值列表。
现在我试图在Widget Factory中做同样的事情,但我能找到的唯一函数是_create,它会被调用每个选中的元素。是否有任何方法可以在Widget工厂中跨所有选定元素使用一个公共初始化函数?还要将所有元素共同的变量作为一个组来使用吗?
希望我已经正确解释了这一点。
P.S。我不想将列表作为选项传递。我希望最终用户程序员尽可能简单。当前插件对SharePoint进行API调用。我宁愿这个复杂性仍然存在于插件中。
我想我可能在这里找到了一个提示: how to declare a static/class variable in a jquery ui widget factory widget
但是xxxpigeonxxx的解决方案不起作用,因为该变量对于所有小部件实例都是通用的,我需要它与所选元素相同。
答案 0 :(得分:0)
这很长。最后解决了你的问题,开始解决了我对jQuery Widget Factory缺乏了解的理解。
jQuery Widget Factory相当严格(与vanilla JS相比,无论如何)。这是一件好事,因为无论作者如何,它都会为所有小部件提供几乎相同的界面。
有些事情我认为你不了解Widgets。
jQuery插件是实用程序函数,它们作用于jquery对象以执行任何操作。 jQuery小部件在元素上创建持久对象。至少,这是他们打算使用的方式。
因此,以表单验证为例:
<强>插件强>
此处,每次提交表单时都会调用validate。
$('.myform').on('submit',function(e){
$(this).find("input").validate(); //checks inputs and adds invalid messages.
if($(this).find(".invalid").length){
e.preventDefault(); //prevent submit if invalid inputs
return false;
}
});
<强>的widget 强>
这里,输入被制作成验证小部件。这可以设置,以便他们在更改,提交或随时自动更新。
$(".myform input").validate({ onchange: true }); // inputs will validate themselves on change.
$('.myform').on('submit',function(e){
if($(this).find(".invalid").length){
e.preventDefault(); //prevent submit if invalid inputs
return false;
}
});
备用窗口小部件
但你可能会做这样的事情:
$(".myform").myform(); // Makes the whole form a single widget that handles all validation
// Now we can listen on custom events
$(".myform").on("myformvalid",function(e,data){
/*Do something now that the form is valid*/
}); // or
$(".myform").on("myformsubmit",function(e,data){
/*Handle a submit*/
});
这些事件是命名空间的,并在销毁时自行清理。
您还可以通过使用选项使表单窗口小部件非常通用:
$(".myform").myform({
validate: { // specify which fields to validate and how
"cost": "number",
"name": "word",
"email": isEmail // function
},
url: "/submit.php" // have the widget handle submitting to server
});
请注意,您也可以使用jquery插件完成所有这些操作。小部件工厂只是一个扩展程序,可以自动执行其中一些操作并标准化界面。
我不想将列表作为选项传递。我想要的东西 对最终用户程序员来说尽可能简单。
使用选项不仅简单,而且是所有小部件的标准。它支持默认值。
假设您要与输入列表创建对话
$('<div>').myDialogue({inputs:"input[title *= 'Cost Center Name']"}).appendTo(/*somewhere*/);
这意味着窗口小部件处理从输入中获取数据,用户只需指定哪些输入。
如果您需要它更灵活,请使用输入数据的数组而不是输入元素:
var listArray = $("input[title *= 'Cost Center Name']").map( function(){
return $(this).val();
});
$('<div>').myDialogue({list:listArray}).appendTo(/*somewhere*/);;
或混合方法。给它元素和可选的解析函数:
$('<div>').myDialogue({
inputs:"input[title *= 'Cost Center Name']",
parseInputs: function(input){ // Optional, has a default
return $(input).val();
}
}).appendTo(/*somewhere*/);
如果您想为每个输入制作单独的小部件
jQuery Widget Factory API就如何在实例之间共享选项提供了一个很好的例子。
var options = { modal: true, show: "slow" }; $( "#dialog1" ).dialog( options ); $( "#dialog2" ).dialog( options, { autoOpen: false });
这两个对话都获得options
个对象,dialog2
获得扩展选项。
<强>附录:强>
这仅涵盖了它们的使用方式以及界面通常的外观。我没有真正实现它们,但有大量的文档。只需了解Widget Factory就很难做出非标准的事情。
以下是选项使用的完整示例。 http://jsfiddle.net/t5Lhquf1/
$.widget("me.mywidget", { // Create the widget
options: {
static1: "1", //defaults
static2: "2",
static3: "3"
},
// Constructor. This is called when mywidget is initialized
_create: function () {
this.element.text(this.options.static1); // Set the elements text as static1
}
});
$(".a").mywidget({ //call it on all .a <p>
static1: "I am part of the .a selection"
});
$(".b").mywidget({ //call it on all .b <p>
static1: "I am part of the .b selection"
});
http://jsfiddle.net/t5Lhquf1/3/
好的,缓存系统给你&#34;静态&#34;键控变量。如果您愿意,可以将两个函数_serverRequest
和_serverRequestOrFromCache
放入窗口小部件中。但是_cache
需要在小部件之外的闭包中。
它要求您传递一个键作为选项。钥匙可以是任何独特的。窗口小部件无法看到对方。即使它们是在一个$('.selector').widget()
中创建的。
此外,这可以改进并可能简化。但这取决于我不知道的有关您的应用的详细信息。
(function () {
// _cache is static for all widgets
// structure is {key1:{data:{},status:"",callbacks:[f1,f2,...]}, key2:{...}}
var _cache = {};
// Do a server request. Run callbacks for this key on finish.
function _serverRequest(key, query) {
console.log("Server Request"); // So we can count how many were performed
_cache[key].status = "inprogress"
var fakeresults = "result of " + query + " with key: " + key;
// $.json(...) // Do your actual query here
// .done( function(){} )
setTimeout(function () { //simulate a server request
_cache[key].data = fakeresults;
_cache[key].status = "done";
$.each(_cache[key].callbacks, function () { // run all callbacks in queue
this(_cache[key].data);
});
_cache[key].callbacks = []; // empty the queue
});
};
// Do a server request unless one is already being performed
// by a widget with the same key. If it is, wait for it to finish
// and use it's result.
function _serverRequestOrFromCache(key, query, callback) {
if (_cache[key] == null) { // if this key is not cached
_cache[key] = {
status: "",
callbacks: [callback],
data: {}
}
_serverRequest(key, query);
} else if (_cache[key].status === "inprogress") { // if another widget is getting data
_cache[key].callbacks.push(callback);
} else if (_cache[key].status === "done") {
// This could be changed to use the cache if the query is the same.
// Currently it only uses the cache if a query is in progress.
_cache[key].callbacks.push(callback);
_serverRequest(key, query);
}
};
$.widget("me.mywidget", { // Create the widget
options: {
key: "default"
},
mydata: {},
// Constructor. This is called when mywidget is initialized
_create: function () {
var that = this;
_serverRequestOrFromCache(this.options.key, "myquery", function (data) {
//callback function
that.mydata = data;
that.element.text(data);
});
}
});
})();
$(".a").mywidget({
key: "a"
});
$(".b").mywidget({
key: "b"
});