我有几个页面,我希望允许用户内联编辑许多字段并更新服务器数据库。为了实现这一点,我的目的是创建一个jQuery插件,我可以通过配置选项的典型传递,并使用ajax来保存结果。
(function($){
var methods = {
init : function (options) {return this.each(function () {/* ... */});},
method1 : function () {return this.each(function () {/* ... */});},
method2 : function () {return this.each(function () {/* ... */});}
};
$.fn.myEditPlugin= function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); //Line 10
} else if (typeof method === 'object' || ! method) {
return methods.init.apply(this, arguments); //Line 12
} else {
$.error('Method ' + method + ' does not exist on jQuery.myEditPlugin');
}
};
}(jQuery)
);
对于每个单独的页面,有几个共同的选项(即url端点,记录的主键等),我不想在应用插件时重复每个选项。
最初,我只是在每个页面上定义一个函数,它接受一些输入并将公共选项应用于每个页面。
function wrapEdit(e,options) {
options.url='/page1/etc';
options.pk=document.getElementById('pk').value;
return $(e).myEditPlugin(options);
}
wrapEdit('.someclass',{foo:123});
这对我来说似乎并不那么专业,所以在我的痴迷追求中,我想我会创建一个可以通过常用选项的类,它会应用插件。
class WrapEdit(options)
{
constructor(options) {
this.options = options;
}
this.applyIndividualOptions=function(e, options) {
return $(e).myEditPlugin(Object.assign({}, this->options, options));
}
}
var wrapEdit=new WrapEdit({url: '/page1/etc', pk: document.getElementById('pk').value});
wrapEdit.applyIndividualOptions('.someclass',{foo:123});
更好,但不是非常jQueryish,因为我将传递select元素,而不是直接将插件应用于jQuery的典型元素。
是否可以创建一个jQuery插件实例来保存以前定义的数据?可能类似于以下内容:
$.myEditPlugin({url: '/page1/etc', pk: document.getElementById('pk').value});
$('.someclass').myEditPlugin({foo:123}); //Will also pass previously defined url and pk to myEditPlugin
或者最好每页创建一个自定义jQuery插件,只需添加额外选项并启动真正的插件......
$.fn.myEditPluginInstance = function(options) {
return this.myEditPlugin(Object.assign({url: '/page1/etc', pk: document.getElementById('pk').value}, options));
};
答案 0 :(得分:1)
创建一个针对jquery集合调用的函数
基本思想是在对插件进行任何调用之前在jQuery.fn
中定义一个新属性(函数)(换句话说,执行与应用程序相关的任何代码)。您可以使用“立即调用的函数表达式”(a.k.a. IIFE)来屏蔽您的插件API。然后您必须遍历集合并执行您的插件需要应用于集合项的任何代码。
基本骨架:
(function ($) {
// Enclosed scope (IIFE)
// You can define private API/variables in here
// …
// Once your plugin API is ready, you have to apply the magic to each item
// in the collection in some ways. You must add a property to jQuery.fn object.
$.fn.myAwesomePlugin = function(Opt) {
var defaultConfig = {option1: 'someValue' /*, …*/};
// Eval supplied Opt object (Validate, reject, etc.)
// If all goes well, eventually merge the object with defaults.
$.extend(defaultConfig, Opt);
// Apply the magic against each item in the jQuery collection
// (Your plugin may not need to use "each" function though)
// Return the jQuery collection anyway to keep chaining possible.
// Once again, this is not required, your plugin may return something else depending on the options passed earlier for instance.
return this.each(function(el, idx) {
// Your plugin magic applied to collection items…
});
}
})(jQuery);
您应该可以在声明后立即调用您的插件$('someSelector').myAwesomePlugin();
。
简单的实施示例:
(function ($) {
let required = {url: null, pk: null}
// Function to be executed upon first call to the plugin
, populateCommons = () => {
let ep = $('#someNode').data('endpoint')
, pk = document.querySelector('#pk')
;
// Basic tests to alert in case the page
// doesn't comply with the plugin requirements
if( typeof ep !== 'string' || !/^\/[a-z]+/.test(ep) || !pk) {
throw ` "myEditPlugin" init phase error:
Detected endpoint: '${ep}'
Is PK value found: ${!!pk}
`;
}
[required.url, required.pk] = [ep, +pk.value];
};
$.fn.myEditPlugin = function(Opt) {
let allOpts;
// First call will trigger the retrival of common data
// that should be available as static data somewhere every page source.
!required.url && populateCommons();
allOpts = $.extend({}, Opt, required);
return this.each(function(el, idx) {
// Your logic here, request
console.log("Payload is", allOpts);
});
}
})(jQuery);
function debounce(fn, time) {
debounce.timer && (clearTimeout(debounce.timer));
debounce.timer = setTimeout(() => (fn(), debounce.timer = null), time);
}
$('[type="text"]').keydown(function(e){
debounce(() => this.value && $(this).myEditPlugin({foo:this.value, bar: 'Contextual value'}), 2000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="pk" type="hidden" value="5">
<div id="someNode" data-endpoint="/api/endpoint">
Editing the below input will trigger the plug-in code
</div>
<input type="text" title="Edit me"/>