30.07.2013, 12:53
|
Аспирант
|
|
Регистрация: 30.07.2013
Сообщений: 47
|
|
Написание плагина jQuery
Добрый день.
Нужна помощь в написании плагина. Посмотрел интернет на эту тему - на всех сайтах одна и та же статья, слизанная друг у друга.
Проблема в том, что не получается передать в плагин ни опции, ни название метода, который хочу использовать. Внутри их просто не видно.
Вот кусок кода (взят из статьи - но, раз не работает, значит написали брехню):
jQuery.fn.formValidation = function(options)
{
var settings =
{
fields: {
name: "name",
surname: "surname",
middlename: "middlename",
phoneNumber: "phoneNumber",
zipCode: "zipCode",
city: "city",
address: "address",
email: "email",
password1: "password1",
password2: "password2"
},
other: [], //[name, regExp, текст, положение tooltip]
tooltipPosition: "right"
};
...//всякие приватные функции...
var methods = {
init: function(options)
{
alert(options); //выдает 0
settings = jQuery.extend({}, settings, options);
//тут идет код
},
validate: function()
{
alert(22222222222);
},
isEmpty: function()
{
alert(111111111111);
}
};
var make = function(method)
{
alert(method);
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('Метод с именем ' + method + ' не существует для jQuery.formValidation');
}
};
return this.each(make);
};
})(jQuery);
У меня стоит, как видно alert(method), чтобы посмотреть, что передано. Так вот он всегда пишет цифру 0 - даже если в аргументе стоит какая строка с названием. В общем, как нужно написать, чтобы заработало?
|
|
30.07.2013, 13:33
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
xmlns,
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
jQuery.fn.formValidation = function(options)
{
var settings =
{
fields: {
name: "name",
surname: "surname",
middlename: "middlename",
phoneNumber: "phoneNumber",
zipCode: "zipCode",
city: "city",
address: "address",
email: "email",
password1: "password1",
password2: "password2"
},
other: [], //[name, regExp, текст, положение tooltip]
tooltipPosition: "right"
};
//всякие приватные функции...
var methods = {
init: function(options)
{
alert(options.name); //выдает 0
settings = jQuery.extend(settings, options);
//тут идет код
},
validate: function()
{
alert(22222222222);
},
isEmpty: function()
{
alert(111111111111);
}
};
var make = function(method)
{
alert(method);
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('Метод с именем ' + method + ' не существует для jQuery.formValidation');
}
};
return this.each(function ()
{
make('init', options)
});
}
$({}).formValidation({name: "test"})
</script>
</head>
<body>
</body>
</html>
|
|
30.07.2013, 14:18
|
Аспирант
|
|
Регистрация: 30.07.2013
Сообщений: 47
|
|
Спасибо, сделал наподобие Вашего кода, вроде работает:
function initialize(method)
{
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, Array.prototype.slice.call( arguments, 1 ));
}
else {
$.error('Метод с именем ' + method + ' не существует для jQuery.formValidation');
}
};
return this.each(function()
{
initialize(options); // зачем писать 'init'? А другие методы?
});
Хм, в С++ объукты проще делать, прозрачнее=)
Только вот вопрос: не получается расширить переданные опции... Их снова не видно. Что нужно исправить?
PS А если все же написать 'init', то вместо замены старого свойства - новым, который передали, то они оба почему-то видны...
settings = jQuery.extend(settings, options);
for(var key in settings)
{
alert(settings[key] + ' ' + key);
}
Последний раз редактировалось xmlns, 30.07.2013 в 14:21.
|
|
30.07.2013, 15:04
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
xmlns,
убрать 14 и часть 25 строки или передавать новый fields полностью -- {name: "test"} было просто для примера.
|
|
30.07.2013, 15:48
|
Аспирант
|
|
Регистрация: 30.07.2013
Сообщений: 47
|
|
Убрать объект fields? Ну а нафига тогда настройки по-умолчанию сделали? Нет, а как в других плагинах делают, когда нужно передать объект в объекте?
Короче, промаявшись в опциями, а понял, что ничего нормально не работает из-за тупой передачи данных в методы плагина. Переписал, но все равно не работает, не передаются опции.
if(methods[method])
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
else if(typeof method === 'object')
return methods.init.apply(this, method);
else if(!method)
return methods.init.apply(this, {});
else
$.error('Метод с именем ' + method + ' не существует для jQuery.formValidation');
Если тут сделать alert(method), то браузер покажет следующее, в зависимости от переданных параметров:
initialize('someMethod', options) //Выведит: someMethod
initialize('someMethod') //Выведит: someMethod
initialize(options) //Выведит: [Object] object
Казалось бы, вот - передаем так initialize(options) - в метод init передастся объект с настройками. А мы видим, когда сделаем alert(options) в:
init: function(options)
{
settings = jQuery.extend(settings, options);
alert(options);
...
}
Мы увидим undefined! Что за хрень?
Объясните и покажите кто-нибудь, как передавать названия методов и настроек в плагин?!
|
|
30.07.2013, 16:04
|
Аспирант
|
|
Регистрация: 30.07.2013
Сообщений: 47
|
|
После долгих мучений плагин родил то, что нужно:
function initialize(method)
{
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('Метод с именем ' + method + ' не существует для jQuery.formValidation');
}
};
return this.each(function()
{
initialize(options);
});
|
|
30.07.2013, 16:16
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
xmlns,
methods.init.call а не methods.init.apply -- options это один аргумент а не массив -- хоть и обьект для 5 поста
|
|
30.07.2013, 21:12
|
Аспирант
|
|
Регистрация: 30.07.2013
Сообщений: 47
|
|
Учту.
Сейчас другая проблема:
Передал в плагин настройки (метод init) - все хорошо, видны.
$('#authorizationForm').formValidation(
{
tooltipPosition: "left",
fields: {email: 'email'},
other: [['input[name=password]','','','left']]
});
После этого вызываю другой метод:
$('#authorizationForm').formValidation('isEmpty');
В этом методе использую объект настроек settings, который расширился тем, что я передал в начале:
for(var key in settings)
{
alert(key+': '+settings[key]);
}
И вижу настройки по умолчанию (см. первый пост), а не то, что я передал. Хотя в методе init, если просмотреть все через alert() - настройки расширены. А тут нет... Мистика. Как заставить плагин сохранять настройки, переданные при инициализации, от вызова к вызову?
|
|
30.07.2013, 21:44
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
Сообщение от xmlns
|
Как заставить плагин сохранять настройки, переданные при инициализации, от вызова к вызову?
|
можно хранить настройки в самом инициализированном обьекте в data -- проверять в дате -- есть берём оттуда, если нет берём по умолчанию.
|
|
30.07.2013, 22:03
|
Аспирант
|
|
Регистрация: 30.07.2013
Сообщений: 47
|
|
Если несложно, можете показать код, как это делать?
И два вопроса попутно:
1. Так делают разработчики плагинов?
2. data - это объект, вшитый в JS как его часть?
|
|
|
|