好吧,我已经在这里阅读了几个主题,以及如何在init函数之外访问var,但因为我是javascript的新手并没有弄清楚如何去做。我已经感谢你的时间了。
我正在编写我的第一个jquery插件 - 一个可以排序,搜索文本,高亮行等等的表 - 我正面临一个问题。
在'settings'块,有一个选项i18N:{'x','y'} - 在init方法中我可以像'options.i18N.search'一样访问它。但是在方法* get_table_body *中,在jqxhr.complete的开头(/ *插入选项来管理表数据* /),我无法访问'options.i18N.iSelected'。好吧,我知道所有关于范围,但我可以解决的唯一方法是使'options = $ .extend(settings,option)' - 使其成为全局。
所以,我问你:在这段代码中我可以访问它的另一种方式是什么 - 没有使“选项”全局化?我已经尝试了$ .yTable.options ......以及其他一些组合但没有成功 - 这是我所期待的,因为我不知道自己在做什么。
(function($){
var methods = {
init : function( option ) {
/* Main settings */
var settings = {
tableClass:'yTable', /* the class of the table */
dataFile: 'yTable.php', /* the file that fetch data in JSON format */
dbTable:'yTableDB', /* the database name that holds the data */
tColumns: [''], /* an array with the header titles of the table */
dbTColumns: [''], /* an array with the table name in database */
dbHColor: '#ded', /* Hover color of rows */
dbCColor: '#ded', /* Color of column when sorting */
tStrLen: 1, /* The minimum string length to search */
insertBottonTh: false, /* Can insert header on bottom? */
hasFunctions: false, /* Without extra functions */
canDeleteRow : false, /* Cannot delete single row */
canDeleteRows: false, /* Cannot delete rows */
canSort: false, /* Cannot sort table columns */
/* Options to translate returned text messages */
i18N: {
search : 'Buscar',
confirm : 'Confirmar',
confirmAll : 'Deseja realmente apagar os registros selecionados'
+'? Esta ação não poderá ser desfeita.',
confirmDel : 'Por favor, confirme a remoção deste registro',
iSelected : 'Com selecionados',
noneSelected : 'Para utilizar esta função é necessário que selecione pelo menos um registro.',
remove : 'Excluir'
}
};
/* Simplify options name */
var options = $.extend(settings, option);
var tClass = options.tableClass;
var tFile = options.dataFile;
var tName = options.dbTable;
var tColumns = options.tColumns;
var dbColumns = options.dbTColumns;
var tHoverColor = options.dbHColor;
var tCColor = options.dbCColor;
var tSLength = options.tStrLen;
var tThBottom = options.insertBottonTh;
var tFunctions = options.hasFunctions;
var tcDeleteRow = options.canDeleteRow;
var tcDelete = options.canDeleteRows;
var tcSort = options.canSort;
var yTable='table.'+tClass;
return this.each(function(){
var obj = $(this);
var n=tColumns.length;
if($.isArray(tColumns)&&n>0){
var th=false;
var sort_img=false;
if(tcSort)
sort_img='<div class="sort-img"></div>';
else sort_img='';
if(tFunctions&&tcDelete)
th+='<th width="18"><input type="checkbox" class="check_all" /></th>';
/* Create the header */
$.each(tColumns, function(k,v){
th+='<th title="'+dbColumns[k]+'" class="th'+k+'">'+v+sort_img+'</th>';
});
}
/* Append table to object */
var table='<div id="yTableSearch">'+options.i18N.search+': <input type="text" class="yTSearch" /></div>'
+'<div style="clear:both;"></div><div class="yTableFunctions"></div>'
+'<table class="'+tClass+'"></table>';
obj.append(table);
/* Append delete single row if requested */
if(tcDeleteRow)
th+='<th></th>';
/* Append the headers to table */
$(yTable).append('<thead>'+th+'</thead>');
/* If bottom is requested, insert it - its content is the same of thead */
if(tThBottom)
$(yTable).append('<tfoot>'+th+'</tfoot>');
/* Load the body of the table(tbody) */
methods.get_table_body(tClass, tFile, tName,dbColumns,
tFunctions, tcDeleteRow, tHoverColor, tCColor, tSLength, tThBottom, tcDelete, yTable);
});
},
get_table_body: function(tClass, tFile, tName, dbColumns,
tFunctions, tcDeleteRow, tHoverColor, tCColor, tSLength, tThBottom,
tcDelete, yTable, tCol, qStr){
$(yTable+' input.check_all').prop('checked',false);
/* Parameters to receive(order) */
/* tClass, tFile, tName, dbColumns, tFunctions, tcDeleteRow,tHoverColor,
* tThBottom, tCColor, tSLength, tcDelete, yTable[, tCol][, qStr] */
/*****************************************/
if(!tCol) tCol=':';
var Cols = tCol.split(':');
var rCol = $.trim(Cols[0]);
var sCol = $.trim(Cols[1]);
var colName = $.inArray(sCol, dbColumns);
var qCol='';
var sType='';
var qByName='';
var asort=Array(2);
if(typeof(sCol)=='string' && colName>=0){
var hObj = $(yTable+' thead th[title='+sCol+']')
.prop('class');
var tc=hObj
.match(/th{1}[^a-z]/);
var cObj = $(yTable+' th.'+tc);
var sortImg = $(yTable+' th.'+tc+' div.sort-img');
var order = hObj.match(/ASC|DESC/);
if(cObj.hasClass('DESC')&&rCol=='sstring'){
cObj.removeClass('DESC').addClass('ASC');
sortImg.css('background-position', '-32px 0');
asort=[sCol, 'ASC'];
} else if(cObj.hasClass('ASC')&&rCol=='sstring'){
cObj.removeClass('ASC').addClass('DESC');
sortImg.css('background-position', '-48px 0');
asort=[sCol, 'DESC'];
} else if(rCol=='qstring'&&order!=null){
asort=[sCol, $.trim(order)];
} else {
$(yTable+' th').removeClass('ASC').removeClass('DESC');
$(yTable+' th div.sort-img').css('background-position', '0 0');
cObj.addClass('ASC');
sortImg.css('background-position', '-32px 0');
asort=[sCol, 'ASC'];
}
}
if($.isArray(asort)){
var qCol = asort[0];
var sType = asort[1];
}
if(qStr){
if(qStr.length>=tSLength && typeof(sCol)=='string'){
qByName = qStr;
}
}
/*****************************************/
/* Get data in JSON format */
var jqxhr = $.get(tFile, {
'table':tName,
'cname': dbColumns.join(','),
'column' : qCol,
'sort' : sType,
'sname' : qByName,
'slength' : tSLength
},
function(){
/* Remove tbody to append a new one */
$('table.'+tClass+' tbody').remove();
}).success(function(data){
/* Mount tbody content */
if(data!='norow'){
var rows = $.parseJSON(data);
var i=0;
var tbody=false;
tbody+='<tbody>';
var tr = false;
$.each(rows,function(){
var objf = rows['tr'+i];
tr+='<tr id="tr'+i+'">'
if(tFunctions&&tcDelete)
tr+='<td><input type="checkbox" name="tr'+i+'" class="check" /></td>';
$.each(objf, function(v){
if(v!=='id'){
tr+='<td>'+objf[v]+'</td>';
}
});
if(tcDeleteRow)
tr+='<td><div class="delete_row" id="r'+objf['id']+'"></div></td>';
tr+='</tr>';
i++;
});
} else {
var ncolumns = dbColumns.length;
if(tFunctions&&tcDelete) {
ncolumns++;
}
if(tcDeleteRow)
ncolumns++;
tr = '<tr><td colspan="'+ncolumns+'">...</td></tr>';
}
tbody+=tr+'</tbody>';
$(yTable).append(tbody);
}).error(function(){
alert('Fail');
});
jqxhr.complete(function(){
/* Permit select/deselect all inputs */
$(yTable+' input.check_all').click(function(){
var val = this.checked;
$('.check_all').prop('checked',this.checked);
var input = $(yTable+' tbody input[type=checkbox]');
input.prop('checked', val);
if(input.prop('checked')==true)
input.closest('tr').addClass('ySelected');
else input.closest('tr').removeClass('ySelected');
});
/* Insert options to manage table data */
if(tFunctions&&tcDelete){
if($('div.yTableFunctions').children().length==0){
$('div.yTableFunctions').append(options.i18N.iSelected+': <select class="yTableOperations">'
+'<option class="none"> -- </option></select>'
+' <input type="button" value="'+options.i18N.confirm+'" name="bConfirm" />');
$('div.yTableFunctions').clone().insertAfter(yTable);
}
/* If can delete by selection */
if(tFunctions&&tcDelete){
if($('div.yTableFunctions select.yTableOperations option.delete').length==0){
methods.delete_selected(yTable);
}
}
}
/* If requested to delete single row */
if(tcDeleteRow){
methods.delete_single_row(tClass);
}
/* Stripe table rows */
methods.stripe_table(tClass);
/* Select row on click */
methods.select_on_click(tClass);
/* First verify what column will be hightlighted ... */
var i=parseInt($(yTable+' thead th[title='+sCol+']').index(),10)+1;
/* ... now highlight coresponding column */
$(yTable+' tr td:nth-child('+i+')').css({
'background-color': tCColor
});
/* ... now sort table */
methods.sort_table($(yTable+' div.sort-img'),yTable,tClass,
tFile, tName,dbColumns, tFunctions, tcDeleteRow, tHoverColor, tCColor, tSLength, tThBottom, tcDelete);
/* Highlight on mouse over */
methods.highlight_on_hover(tClass, tHoverColor,tCColor);
methods.search_string(tClass, tFile, tName, dbColumns, tFunctions, tcDeleteRow,
tHoverColor, tCColor, tSLength, tThBottom, tcDelete, yTable);
});
},
stripe_table: function(c){
$('table.'+c+' tbody tr').removeClass('stripes');
$('table.'+c+' tr:nth-child(even)').addClass('stripes');
},
highlight_over_highlighted_cell: function(trId,c,h){
$('table.'+c+' thead th').each(function(){
if($(this).hasClass('ASC')||$(this).hasClass('DESC'))
var thId = true;
if(thId){
var tHClass=$(this).prop('class').match(/th{1}[^a-z]/);
/* First verify what column will be hightlighted ... */
var i=parseInt($('table.'+c+' thead th.'+tHClass).index(),10)+1;
/* ... now highlight coresponding cell */
$('table.'+c+' tr#'+trId+' td:nth-child('+i+')').css({
'background-color': h
});
}
});
},
highlight_on_hover: function(c,h,rh){
var thisTr = $('table.'+c+' tbody tr');
thisTr.mouseover(function(){
/* Tr id */
var thisTrId=$(this).prop('id');
$(this).css({
'background-color':h
});
methods.highlight_over_highlighted_cell(thisTrId,c,h);
}).mouseout(function(){
$(this).css('background-color','');
/* Tr id */
var thisTrId=$(this).prop('id');
methods.highlight_over_highlighted_cell(thisTrId,c,rh);
});
},
select_on_click:function(c){
$('table.'+c+' tbody tr').click(function(){
var $this = $(this);
var input = $this.children('td').children('input');
/* Select/desselect row input */
input.prop('checked', input.prop('checked')?false:true);
/* Toggle highlight*/
if(input.prop('checked')==true)
$this.addClass('ySelected');
else $this.removeClass('ySelected');
});
},
delete_single_row : function(c){
$('div.delete_row').click(function(){
$(this).closest('tr').addClass('highlight_row');
// var rId = this.id.replace(/r/,'');
if(confirm(options.i18N.confirmDel)){
// $.get('delete_row.php',{
// id:rId
// },
// function(data){
// alert(c);
// });
$(this).closest('tr').hide();
}else{
$(this).closest('tr').removeClass('highlight_row');
}
});
},
delete_selected: function(c){
var oper = $('select.yTableOperations');
oper.append('<option class="delete" value="delete">'+options.i18N.remove+'</option>');
oper.change(function(){
var opt = $(this).val();
oper.each(function(){
$(this).prop('value',opt);
});
});
$('.yTableFunctions input[type=button]').click(function(){
if(this.value === options.i18N.confirm && oper.val()==='delete'){
var regs=[];
var i=0;
$(c+' input[type=checkbox].check')
.each(function(){
if(this.checked){
regs[i] = this.name;
$('tr#'+regs[i]).addClass('highlight_row');/* Highlight marked rows */
i++;
}
});
if(regs.length>0){
var rows=[];
if(confirm(
options.i18N.confirmAll
)){
$.each(regs, function(k,v){/* Loop through each row */
rows[k]='"'+k+'":"'+v+'"';
$('tr#'+v).addClass('highlight_del')/* Highlight to delete */
.hide('slow') /* Give some time to hide */
.remove();/* Remove row */
});
rows = '{'+rows.join()+'}';
$(c+' input[type=checkbox].check_all')
.prop('checked',false);
} else {
$('tr').removeClass('highlight_row');
}
}else{
alert(options.i18N.noneSelected);
}
}
});
},
sort_table : function(ce,yTable, tClass, tFile, tName,dbColumns,
tFunctions, tcDeleteRow, tHoverColor, tCColor, tSLength, tThBottom, tcDelete){
$(ce).unbind('click').click(function(e){
e.stopPropagation();
var tCol='sstring:'+$(this).closest('th').prop('title');
var qStr=$('#yTableSearch input.yTSearch').val();
/* Get data sorted */
methods.get_table_body(tClass, tFile, tName,dbColumns, tFunctions,
tcDeleteRow, tHoverColor, tCColor, tSLength, tThBottom, tcDelete, yTable, tCol, qStr);
});
},
search_string : function(tClass, tFile, tName,dbColumns, tFunctions, tcDeleteRow,
tHoverColor, tCColor, tSLength, tThBottom, tcDelete, yTable){
$('#statistics').unbind('keyup').on('keyup', '#yTableSearch input.yTSearch',
function(e){
e.stopImmediatePropagation();
var qStr=null;
if(this.value.length>=tSLength
&&((e.keyCode>46&&e.keyCode<91)
||(e.keyCode>95&&e.keyCode<106))
||e.keyCode==8||e.keyCode==46
){
qStr = this.value;
var noSort = 'qstring:';
$(yTable+' thead tr th').each(function(e){
if($(this).hasClass('ASC')|| $(this).hasClass('DESC')){
noSort += $(this).prop('title');
}
})
methods.get_table_body(tClass, tFile, tName,dbColumns, tFunctions,
tcDeleteRow, tHoverColor, tCColor, tSLength, tThBottom, tcDelete, yTable, noSort, qStr);
}
});
}
};
$.fn.yTable=function(method){
/* Method calling logic */
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Desculpe-me, mas o método "' + method + '" não existe no plugin yTable!' );
}
};
})(jQuery);
有效!感谢您抽出宝贵时间帮助我解决这个问题。我将把解决方案放在下面,因为其他人可能会遇到同样的问题。遵循@ Beetroot-Beetroot指令,我对这个问题感到不安。
修改很少......见下文
方法初始化:
首先,我从设置中撤回i18N块并将其放入返回this.each()
init : function( options ) {
// codes ...
return this.each(function(){
var obj = $(this);
var data = obj.data('yTable');
data ={
/* Options to translate returned text messages */
i18N: {
target : obj,
search : 'Buscar',
confirm : 'Confirmar',
confirmAll : 'Deseja realmente apagar os registros selecionados'
+'? Esta ação não poderá ser desfeita.',
confirmDel : 'Por favor, confirme a remoção deste registro',
iSelected : 'Com selecionados',
noneSelected : 'Para utilizar esta função é necessário que selecione pelo menos um registro.',
remove : 'Excluir',
showReg : 'Mostar ',
showRegEnd : ' por página',
failDbQuery : 'Erro! Não foi possível buscar dados na base de dados. Por favor, verifique sua configuração.'
}
}
obj.data('yTable', data);
// var options = $ .extend(data,options); var yOptionLang = obj.data('yTable');
现在我可以通过 yOptionLang.i18N.showReg 访问 init 中的i18N。因为我需要将i18N传递给方法 get_table_body ,所以我通过执行* methods.get_table_body(tClass ... yTable).apply(this)*。
当我从 get_table_body 调用其他方法时,我将其重写为......
get_table_body:function(tClass,...nReg){
return $.each(function(){
var yOption = $(this).data('yTable');
// code here ...
我可以通过 yOption.i18N.iSelected 来访问i18N ...现在,在这个方法中我必须将i18N传递给其他方法,所以我这样做......
/* If requested to delete single row */
if(tcDeleteRow){
methods.delete_single_row(tClass).apply(yOption);
}
...在这种情况下,方法 delete_single_row 将以...开头
delete_selected:function(c){
return $.each(function(){
var yOption = this;
// code here...
...我可以通过 yOption.i18N.remove
访问i18N其他棘手的问题是,我需要从其他方法调用 get_table_body ,所以我必须在这些方法中添加 .apply(this),如下所示对表格进行排序。
sort_table:function(ce,yTable, tClass, tFile, tName,dbColumns,
tFunctions, tcDeleteRow, tHoverColor, tCColor, tSLength, tThBottom, tcDelete){
$(ce).unbind('click').click(function(e){
e.stopPropagation();
var tCol='sstring:'+$(this).closest('th').prop('title');
var qStr=$('#yTableSearch input.yTSearch').val();
var nReg = $('div#yTableRegs select#yTableRegSelect').prop('value');
/* Get data sorted */
methods.get_table_body(tClass, tFile, tName,dbColumns, tFunctions,
tcDeleteRow, tHoverColor, tCColor, tSLength, tThBottom, tcDelete, yTable, tCol, qStr, nReg).apply(this);
});
}
嗯,现在通过这些修改我可以将变量从方法传递给方法 - 谢谢你的帮助!
答案 0 :(得分:1)
这种模式非常聪明,但很难渗透。
要理解的主要内容是:
var methods = ...
之前)将是对插件本身的特定(和私有),而不是对它的任何特定调用因此,没有明显的方法在方法之间共享变量。
幸运的是,jQuery使得在DOM中存储数据变得简单,而这正是这里所必需的。
以下是init的模板,基于教程 here :
init : function(options) {
return this.each(function(index){
var $this = $(this);
var data = $this.data(pluginName);
// If the plugin hasn't been initialized yet
if (!data) {
var settings = {
//default settings here
};
if(options) { $.extend(settings, options); }
data = {
target : $this,
//other data properties here
}
$this.data(pluginName, data);
//do other init stuff here
//create further data properties as required
}
});
},
因此,在init中建立的数据可用于其他方法:
myMethod : function() {
return this.each(function(index){
var $this = $(this);
var data = $this.data(pluginName);
//do other method stuff here
//access data properties as required
});
},