jQuery UI Widget工厂中常见的初始化/公共变量?

时间:2014-12-15 21:40:48

标签: jquery jquery-ui jquery-plugins

我有一个成功运行的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的解决方案不起作用,因为该变量对于所有小部件实例都是通用的,我需要它与所选元素相同。

1 个答案:

答案 0 :(得分:0)

这很长。最后解决了你的问题,开始解决了我对jQuery Widget Factory缺乏了解的理解。

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"
});

编辑2

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"
});