12.08.2011, 16:37
|
|
Интересующийся
|
|
Регистрация: 12.08.2011
Сообщений: 15
|
|
Передача параметров в колбэки и дальнейшее их вешанье на события.
Не могу понять как передать параметры в коллбэки и повесить колбэки на события. Т.е. если у колбэка есть параметры, то он срабатывает не по наступлению события, мгновенно после загрузки страницы.
Не получается это сделать ни на чистом JavaScript, ни на jQuery.
Например. есть некая функция
methodName: function(par1,par2,callbackName){
$('#someId').bind('click',callbackName);
}
если в параметр callbackName вошла функция без параметров, то она запустится по наступлению события клика на someId, а если в параметр callbackName вошла функция с параметрами, то она запускается мгновенно.
Уже испробовал следующие варианты:
$('#someId').click(myCallback);
$('#someId').Click = myCallback;
$('#someId').attr('onClick',myCallback); $('#someId').bind('click',myCallback);
Ничего не выходит.
Вызвать после наступления события функцию с параметрами помогло только следующее:
<button onclick="SomeObject.methodName(<?=$par1?>, <?=$par1?>)">doSomethind</button>
Знаю что это не очень красиво, что нельзя мешать JS и HTML, но это единственный рабочий способ, который я нашел. К тому-же ВКонтакте делаются так-же, суда по просмотру исходного кода.
Но как в функцию передать колбэк с параметрами и повесить его на событие ВНУТРИ функции, в которую он передается - не могу понять . Этот гад - колбэк запускается мгновенно.
Помогите, кто сталкивался с такой задачей.
|
|
12.08.2011, 16:54
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
methodName: function(par1,par2,callbackName){
$('#someId').bind('click',function(){
callbackName(par1, par2);
});
}
|
|
12.08.2011, 18:24
|
|
Интересующийся
|
|
Регистрация: 12.08.2011
Сообщений: 15
|
|
К сожалению этот способ не помогает - все немного сложнее.
Задача - создать окно, аналогичное по функциям Джаваскриптовскому Confirm. Но чтобы оно было красивое ))). Функция получает в себя строки, которые будут выводитья в окне, и callback-функцию, которая будет быполняться в случае нажатия на кнопку подстверждения.
Вот функция вывода окна:
areYouSure: function(title,question,okText,cancelText,myCallback){
$.ajax({
url: "/views/V_Common/V_AreYouSure.php", //получаем с сервака ХТМЛ-код будущего окна
dataType: "html",
success: function(data) {
var sureBox = $(data); //начинаем создавать ДОМ-Элемент
sureBox.attr('title',title);
sureBox.find('p').text(question);
sureBox.find('#ok').text(okText);
sureBox.find('#ok').bind('click',myCallback); /*вешаем колбэк, на кнопку ОК (который, меня уже задолбал сразу запускаться)*/
sureBox.find('#ok').click(function(){sureBox.dialog( "close" );});
sureBox.find('#cancel').text(cancelText);
sureBox.find('#cancel').click(function(){sureBox.dialog( "close" );});
sureBox.appendTo($('body')); /*Запихиваем новый элемент в ДОМ и делаем из него выпадающее окошко при помощи jQuery UI*/
sureBox.dialog({resizable: false,
draggable: false,
modal: true,
show: 'fade',
hide: 'fade',
position: ['center',180]
});
},
error: function (XMLHttpRequest, textStatus, errorThrown){
Common.makeAlert('AJAX не прокатил', 'Какая-то ошибка');
}
});
}
Простой пример использования данной функции:
askLogout: function(){
this.areYouSure('Предупреждение', 'Вы уверенны что хотите выйти?', 'Выйти', 'Нет', this.logout())
},
logout: function(){
document.location.href = "/logout/";
},
Пример использования чуть посложнее:
Common.areYouSure('Предепреждение',
'После удаления группу будет невозможно восстаеновить.Вы уверены что хотите удалить эту группу?',
'Удалить группу', 'Отмена',
Groups.destroy(id_group));
destroy: function(id_group){
//alert('Удалялка группы' + id_group);
$.ajax({
type: "POST",
url: "/index.php?controller=C_Groups&method=destroyGroup",
data: 'id_group=' + id_group,
dataType: "xml",
success: function(data) {
var canDestroy = $(data).find('canDestroy').text();
switch (canDestroy) {
case 'yes':
Common.makeAlert('Поздравляем!', 'Вы удалили данную группу');
break;
case 'notOwner':
Common.makeAlert('Предупреждение!', 'Вы не можете удалить эту группу потому-что не являетесь ее владельцем');
break;
default:
break;
}
},
error: function (XMLHttpRequest, textStatus, errorThrown){
Common.makeAlert('AJAX не прокатил', 'Какая-то ошибка');
}
});
}
Это к тому что каждый раз в колбэк может передаваться разное количество параметров, а могут не передаваться и вовсе. И функции - колбэки могут быть слишком громоздкими, для того чтобы - делать их анонимными.
Пока-что я нашел такой рабочий способ вызова, но он не очень хорош:
askLogout: function(){
this.areYouSure('Предупреждение',
'Вы уверенны что хотите выйти?',
'Выйти',
'Нет',
function(){Common.logout()})
},
Данный способ плох по следующей причине:
logout и areYouSure являются методами одного и того-же обьекта common. Приходиться вызывать метод текущего объекта не по-человечески через this (this.logout()), а через конкретно его имя (Common.logout()), что не очень-то красиво.
Я даже вопрос немного переформулировал:
Как правильно и красиво передать внутрь функции А параметром функцию Б в виде колбека, чтобы выполнилось следующее:
1 - Функция Б (колбэк) будет подписана на событие внутри функции А
2 - Функция Б может оказатья любой, следовательно количество передаваемых параметров в функцию Б может быть различное.
|
|
12.08.2011, 18:47
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
погодь, тебе нужно просто передать параметр this ?
sureBox.find('#ok').bind('click',function(){
myCallback.call( Common );
// или
// myCallback.apply( Common, arguments );
});
|
|
12.08.2011, 19:58
|
|
Интересующийся
|
|
Регистрация: 12.08.2011
Сообщений: 15
|
|
Нет, параметр this передавать не нужно.
Мне нужно было следующее (уже сделал что хотел ):
Так не работало и вызывало метод не дожидаясь события
Common.areYouSure('Предепреждение',
'После удаления группу будет невозможно восстаеновить.Вы уверены что хотите удалить эту группу?',
'Удалить группу', 'Отмена',
Groups.destroy(id_group));
Так работало, но код выглядел как-то корявенько
Common.areYouSure('Предепреждение',
'После удаления группу будет невозможно восстаеновить.Вы уверены что хотите удалить эту группу?',
'Удалить группу', 'Отмена',
function(){Groups.destroy(id_group)});
А так стало аккуратно выглядеть и при этом работать как нужно .
Common.areYouSure('Предепреждение',
'После удаления группу будет невозможно восстаеновить.Вы уверены что хотите удалить эту группу?',
'Удалить группу', 'Отмена',
Groups.destroy.call(id_group));
Тем не менее большое спасибо за советы тебе, Devote . Ты натолкнул меня на мысль передать параметр не в скобках а через Call. С ним все заработало как и требовалось.
Хотя осталось смутное предчувствие по поводу этого хитрого метода call : насколько я понял, он необходим как-раз для передачи параметров в функции - колбэки. Но помоему я неправильно понял ...
В справочнике на этом сайте есть его описание, но чет не могу понять полностью его предназначение. Не мог бы ты подсказать, как говориться, на пальцах, для чего он еще нужен?
|
|
12.08.2011, 20:46
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
Groups.destroy.call(id_group)
И это работает?? Я удивлен, обычно первым параметром передается то кем будет this
а вообще он нужен скажем вот:
function myFunc( myParam ) {
alert( this ); // это прототип объекта qwerty
alert( myParam ); // 'param1'
}
(function(){
var qwerty = function( callback ) {
return new qwerty.prototype.init( callback );
}
qwerty.prototype = {
constructor: qwerty,
init: function( callback, param ) {
callback.call( this, 'param1', 'param2' );
return this;
},
test: function( callback ) {
callback.apply( this, arguments );
return this;
}
}
qwerty.prototype.init.prototype = qwerty.prototype;
window.qwerty = qwerty;
})();
qwerty( myFunc ).test( function(){
alert( this ); // это прототип объекта qwerty
alert( Array.prototype.slice.call( arguments, 0 ).splice(1) ); // 'arg1', 'arg2', 'arg3'
}, 'arg1', 'arg2', 'arg3');
вообщем через нее можно передавать аргументы совершенно любое количество в любую функцию
|
|
12.08.2011, 21:13
|
sinistral
|
|
Регистрация: 28.03.2011
Сообщений: 5,418
|
|
Сообщение от devote
|
Groups.destroy.call(id_group)
И это работает?? Я удивлен, обычно первым параметром передается то кем будет this
|
интересно получилось. хотя, в JS всё - объекты. может ли это стать паттерном ?
осталось подумать,как это можно использовать.
(function(){ alert(this[0]) }).call(["hello!"]);
iterator = function(a,b){ alert(a+b) };
(function(a){ for(var i in this) a(i,this[i]); }).call({" one ":" hello "},iterator);
удивляюсь просто, нигде такого ещё не встречал
Последний раз редактировалось melky, 12.08.2011 в 21:15.
|
|
12.08.2011, 21:19
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
(function(){ alert(this); alert(arguments[0]) }).call("hello", "World!!!");
|
|
12.08.2011, 22:29
|
|
Интересующийся
|
|
Регистрация: 12.08.2011
Сообщений: 15
|
|
Пока не поздно - отпишусь. Все как работало криво, так и работает криво . Буду дальше пытаться через call передать...
|
|
12.08.2011, 22:35
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
если как нить по нормальному объяснишь что надо, то разберемся... а то я понять не могу что конкретно надо, сделай миниатюру, не вырезай из своего кода куски, сделай пример того как у тебя все построено и что требуется, тогда и решение быстро найдется.. вот так же как миниатюрный пример сделал я, который тут можно запустить, так же и ты сделай
Последний раз редактировалось devote, 12.08.2011 в 22:42.
|
|
|
|