PDA

View Full Version : سوال: اداره کننده کلاس و توابع در jquery



aminghaderi
جمعه 30 تیر 1391, 01:22 صبح
با سلام خدمت تمامی دوستان
در کار با jquery به نکته جالبی رسیدم ، اینکه ما اگر شی یا پلاگینی در آن بسازیم به راحتی می تونیم در تعداد مورد نظر در صفحه استفاده کنیم ، بدون اینکه بخواهیم خودمون ترتیب اجرای اونها رو تعریف و مدریریت کنیم.
این در حالی هست که در جاوااسکریپت برای ساخت اشیا و استفاده از اونها به تعداد ، حتمی باید برای آن اداره کننده طراحی و ایجاد کنیم.

مثال از روی کد :

var StrID;
(function($) {
$.fn.AA = function(e) {
StrID = $(this).attr('id');
function G(IntPageIndex) { alert(StrID); };
G(a);
};

})(jQuery);

فراخوانی :

$("#Div1").AA();
$("#Div2").AA();
$("#Div3").AA();
$("#Div4").AA();
$("#Div5").AA();

هر کدام از این توابع که اجرا می شوند ، با اینکه از یه کلاس گرفته شدند و متغیر عمومی استفاده کردند ، اصلا با هم دیگر قاطی نمی شوند ، هر کدام کار خودشان را انجام می دهند .

ممنون می شوم در صورت اطلاع از کار این اداره کننده یه توضیح مختصر بدهید ؟

با تشکر.

Variable
جمعه 30 تیر 1391, 02:26 صبح
میشه یه کم توضیح بدید؟
منظورتون کدوم متغیر عمومی هست ؟
در جاوا اسکریپت شما با هر بار فراخوانیه یک تابع خاص . (یک شی و )یک فضای خاص برای اون فراخوانی تابع در حافظه میسازی.
که کاملا با هم متقاوت هستند چون هر کدام درخانه هایی متمایزی در حافظه ساخته شدند

aminghaderi
یک شنبه 01 مرداد 1391, 14:14 عصر
سلام.
ممنون بایت پاسخ شما.

میشه یه کم توضیح بدید؟ منظورم روش کار $.fn هست که چطور اشیا رو مدریت می کند .

مثال بالا جنبه عملیاتی نداره ، همانطوری نوشتم تا موضوع روشن بشود و حق با شماست ، من اون e رو متغیر عمومی می دونستم ، که توی این چند روزه که روی پروژه کار می کردم و دسترسی به اینترنت هم نداشتم ، فقهمیدم که e متغیر عمومی نیست و کاملا خصوصی هست ولی چطور جی کوئری و جاوا اسکریپت به اون ها دسترسی دارند ، موضوعی هست که من همین الان بروی پروژه به ان بخوردم و کارم رو به نحوی حل کردم ولی می دونم اصولی نیست و یه جورایی شبیه سازی این مدیریت متغیر های خصوصی بود .

در جاوا اسکریپت شما با هر بار فراخوانیه یک تابع خاص . (یک شی و )یک فضای خاص برای اون فراخوانی تابع در حافظه میسازی.
که کاملا با هم متقاوت هستند چون هر کدام درخانه هایی متمایزی در حافظه ساخته شدند این رو می دونم ولی نمی تونم به اون مقادیر دسترسی داشته باشم؟؟
الان باید چطوری متغیر x که به دو شی انتساب داده شده رو دریافت کرد؟؟ مثل x تابع اول رو به دست آورد؟؟

Variable
یک شنبه 01 مرداد 1391, 17:40 عصر
چرا میتونید .
با مفهوم scope chain یعنی زنجیره دید . . در جاوا اسکریپت هر متغیری که با var تعریف بشه . به صورت خصوصی در میاد بهتر بگم همون protected در زبان سی شارپ
حالا برای دسترسی به این متغیر از خارج از تابع. شما باید این متغیر رو به خارج از تابع بفرستی
.یکیش اینه که اینرو با var تعریف نکنی . تا بشه سراسری . همه بتونن متغیرت رو ببینند. که اونوقت توسط همه مورد تغییر قرار میگیره.
یا اینکه مقدار این متغیررو توسط return تابع به عنوان خروجی باز گردونی .

وراه حل بهتر ش اینه که شما از مفهوم closure استفاده کنی و از این طریق توابعی بنویسی که بتونن به متغیر های خصوصیه تابع دسترسی داشته باشند.
که زیاد دربارش صحبت نشده .

eAmin
یک شنبه 01 مرداد 1391, 21:07 عصر
درمورد قاطی نشدن بزارید این رو برای شما توضیح بدیم، بصورت کلی $.fn یعنی میانبری برای jQuery.prototype و این به این معنا است که هر متدی به این شئ اضافه کنید، عضوی از شئ jQuery میشه.
وقتی شما دارید بصورتی که در پست اولتون مثال زدید، متدی رو که ساختید فراخوانی میکنید، در پشت پرده این عملیات صورت میگیره:


new jQuery('aaa').AA();

قسمتی از کد jQuery که این وظیفه رو داره در اینجا آورده شده:


var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context );
},

این علت اینکه متدها با هم تداخل پیدا نمیکنند چون در هر بار فراخوانی یک شئ جدید توسط کلمه ی کلیدی new ساخته میشه.

باقی مواردی که مطرح کردید راستش بنده هنوز متوجه نشدم! میتونید برای هریک از اینهایی که نقل کردم یک مثال عملی بزنید؟


این در حالی هست که در جاوااسکریپت برای ساخت اشیا و استفاده از اونها به تعداد ، حتمی باید برای آن اداره کننده طراحی و ایجاد کنیم.

مثال بالا جنبه عملیاتی نداره ، همانطوری نوشتم تا موضوع روشن بشود و حق با شماست ، من اون e رو متغیر عمومی می دونستم ، که توی این چند روزه که روی پروژه کار می کردم و دسترسی به اینترنت هم نداشتم ، فقهمیدم که e متغیر عمومی نیست و کاملا خصوصی هست ولی چطور جی کوئری و جاوا اسکریپت به اون ها دسترسی دارند ، موضوعی هست که من همین الان بروی پروژه به ان بخوردم و کارم رو به نحوی حل کردم ولی می دونم اصولی نیست و یه جورایی شبیه سازی این مدیریت متغیر های خصوصی بود .
شما چطور متوجه شدید که jQuery میتونه به اون متغیر/آرگومان یعنی همون e دسترسی داشته باشه؟ این مورد رو اگر کمی واضح تر و با مثال توضیح بدید، مساله تازه روشن میشه!

این رو می دونم ولی نمی تونم به اون مقادیر دسترسی داشته باشم؟؟
الان باید چطوری متغیر x که به دو شی انتساب داده شده رو دریافت کرد؟؟ مثل x تابع اول رو به دست آورد؟؟
کدام مقادیر؟
در مورد متغیر x هم تقریبا مثل توابع دسترسی در cpp میشه عمل کرد:

var x = 10;

var a = function() {
this.x = x + 10;
};

new a().x;

// or

var b = function() {
x = 30;
this.x = x;
}

b.prototype.getX = function() {
return this.x;
}

new b().getX();

یا شاید اصلا منظورت این نباشه، اگر اینطور هست بهتره مثال عملی بزنید تا شاید بشه بهتر توضیح داد.

Variable
یک شنبه 01 مرداد 1391, 22:58 عصر
بله این خیلی خوب بود...

aminghaderi
دوشنبه 02 مرداد 1391, 02:42 صبح
سلام مجدد.

میتونید برای هریک از اینهایی که نقل کردم یک مثال عملی بزنید؟
بله حتمی.

این در حالی هست که در جاوااسکریپت برای ساخت اشیا و استفاده از اونها به تعداد ، حتمی باید برای آن اداره کننده طراحی و ایجاد کنیم.
برای مثال ما یه کلاسی یا شی بنام menu داریم که اتفاقا اجکسی هم هست ، اگر بخواهیم به صورت معمول یک نسخه در صفحه اضافه کنیم ، که هیچ مشکلی پیش نمی یاد ، ولی اگر قرار باشه 4 تا اضافه کنیم ، یا چیزی اجرا نمی شه یا اگر هم اجرا بشه یه صفحه بهم ریحته خواهیم داشت . (شخصا تجریه کردم) دلیل این موضوع هم از اجکس است و هم از پردازش تفسیری جاوااسکریپت ، که همه چیز پشت سر هم اجرا می شود که من این کار رو با شبیه سازی یه تایمر طراحی کرده بودم که کار می کرد ولی ولی اون جوری که من توقع داشتم منطقی به نظر نمی رسید و اصلاحا مهندسی نبود ، تا همین چند وقت پیش توی همین بخش مطرح کردم ، دوستی لطف کرد و یه راه حل منطقی تر و اساسی تر ارائه داد که من رو به نتیجه واقعا بهتری رساند ! (می تونید از این لینک (http://barnamenevis.org/showthread.php?349944-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-jQuery-%D8%A8%D9%87-%D9%87%D9%85%D8%B1%D8%A7%D9%87-%DA%A9%D8%AF-%D9%87%D8%A7%DB%8C-JavaScript) درجریان راه حل قرار بگیرد ) با استفاده از اون روش من تونستم یه اداره کننده هر چند کوچک و ناچیز ، اما مفید برای کارهای شخصیم طراحی کنم .


کاملا خصوصی هست ولی چطور جی کوئری و جاوا اسکریپت به اون ها دسترسی دارند
پلاگینی شخصی نسبتا بزرگی دارم که به چند پلاگن دیگه متصل شده و به راحتی بدون ایراد کار می کنند ، توسط خود من پلاگین ایجاد شده ولی حقیقا انتهای کار از روند منطقی کار اون درست سر در نیاوردم که چطوری یه شی ایجاد شد ، بعد اون دو تا شی دیگر هم ایجاد می شود که به راحتی به متغیر های هم دیگر دسترسی دارند و جالب اینجا بود که اگر 3 تا 4 تا شی از پلاگین اصلی هم به صفحه اضافه می شد ، هیچ ایرادی به وجود نمی آمد که با توضیحاتی که دوستمون فرمودند قضیه کمی روشن شد :

حالا برای دسترسی به این متغیر از خارج از تابع. شما باید این متغیر رو به خارج از تابع بفرستی
چون اساس کار پلاگین هم بر همین مورد استوار هست ، مقادیر کلاس فعلی را به صورت ورودی به کلاس بعدی منتقل می کند و من این مورد رو درک نمی کردم که اون داره متغیر (e) مربوط به شی جدید از پلاگین رو منتقل می کند .
یعنی ما در 3 بار استفاده از پلاگین سه تا e مختلف دارم که با توضیحات شما این مسئله برای من کاملا روشن شد :


درمورد قاطی نشدن بزارید این رو برای شما توضیح بدیم، بصورت کلی $.fn یعنی میانبری برای jQuery.prototype و این به این معنا است که هر متدی به این شئ اضافه کنید، عضوی از شئ jQuery میشه.
وقتی شما دارید بصورتی که در پست اولتون مثال زدید، متدی رو که ساختید فراخوانی میکنید، در پشت پرده این عملیات صورت میگیره:
1
2
new jQuery('aaa').AA();




قسمتی از کد jQuery که این وظیفه رو داره در اینجا آورده شده:
1
2
3
4
5
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context );
},




این علت اینکه متدها با هم تداخل پیدا نمیکنند چون در هر بار فراخوانی یک شئ جدید توسط کلمه ی کلیدی new ساخته میشه.



یا شاید اصلا منظورت این نباشه، اگر اینطور هست بهتره مثال عملی بزنید تا شاید بشه بهتر توضیح داد.
نه دقیقا همین بود و سپاسگذارم ، از اینکه وقت گذاشتید تا مشکل من حل بشه ، تست می گیرم ، خبرش رو می دم .

با تشکر مجدد و فراوان.

aminghaderi
دوشنبه 02 مرداد 1391, 05:02 صبح
نه متاسفانه ، نتیجه مورد نظر حاصل نشد .
برای مثال :
پلاگینی (فرضا) به صورت زیر ایجاد کردیم :

(function($) {
$.fn.AA = function(e) {
alert(e.Name);
};
})(jQuery);


حالا دو بار از اون روی صفحه اصلی مان استفاده می کنیم :

$('Div1').AA({ Name: 'Amin' });
$('Div2').AA({ Name: 'Reza' });


حالا چطوری می شود ، بعد از اجرا این دو دستور در آخر ما مقدار Name هر کدام رو جدا داشته باشیم؟؟

//alert(مقدار name اولین دستور);
//alert(مقدار name دومین دستور);

eAmin
دوشنبه 02 مرداد 1391, 19:39 عصر
برای مثال ما یه کلاسی یا شی بنام menu داریم که اتفاقا اجکسی هم هست ، اگر بخواهیم به صورت معمول یک نسخه در صفحه اضافه کنیم ، که هیچ مشکلی پیش نمی یاد ، ولی اگر قرار باشه 4 تا اضافه کنیم ، یا چیزی اجرا نمی شه یا اگر هم اجرا بشه یه صفحه بهم ریحته خواهیم داشت . (شخصا تجریه کردم) دلیل این موضوع هم از اجکس است و هم از پردازش تفسیری جاوااسکریپت ، که همه چیز پشت سر هم اجرا می شود که من این کار رو با شبیه سازی یه تایمر طراحی کرده بودم که کار می کرد ولی ولی اون جوری که من توقع داشتم منطقی به نظر نمی رسید و اصلاحا مهندسی نبود

در مورد menu مطمئنا بخاطر پیاده سازی نادرست در JavaScript بوده. در JavaScript قابلیت Asynchronous رو به بهترین و ساده ترین شکل ممکن میشه پیاده سازی کرد. مثالی که شما در اون تاپیک زدید، می خواستید بصورت Synchronous باشه، و این برای وقتی که پای Ajax در میون باشه غیر ممکن هست. دلیلش هم واضح است. سرعت پردازش کدها در حد میلی ثانیه هست در حالی که وقتی شما درخواستی به سمت سرور می فرستید خودش ممکنه چندین ثانیه طول بکشه و اینکه منتظر جواب سرور باشید! به همین خاطر هست که نمیشه از حالت همزمان در پیاده سازی این اسکریپتها استفاده کرد. بهترین راه حل در این موارد پیاده سازی بصورت غیر همزمان هست. یک مثال ساده:

var MyClass = new function() {
var StrVariable = "";
var IntVariable = 0;

this.A = function AA(callback) {
jQuery(function() {
$.ajax({
type: "POST",
url: "A.ashx/GET",
data: "{ID:'1'}",
contentType: "application/json",
dataType: "json",
success: function(msg) {
callback(msg);
},
error: function() { alert("در سرور خطایی رخ داده است!"); }
});
});

}

this.B = function BB() {
this.A(function(msgData) {
//
//می خوام بتونم ادامه متد رو اینجا بنویسم
//که با خطا مواجه میشم.
//

alert(msgData);
});
}
}



حالا چطوری می شود ، بعد از اجرا این دو دستور در آخر ما مقدار Name هر کدام رو جدا داشته باشیم؟؟

یا میتونید مثل مثالی که بالا براتون زدم عمل کنید و یا متغیر e رو بازگشت بدید:

(function($) {
$.fn.AA = function(e) {
alert(e.Name);
return e;
};
})(jQuery);

var d1 = $('Div1').AA({ Name: 'Amin' });
var d2 = $('Div2').AA({ Name: 'Reza' });

console.log(d1.Name); // Amin
console.log(d2.Name); // Reza

یا

var arr = [];

(function($) {
$.fn.AA = function(e) {
eval("arr.push({ " + $(this).attr('id') + " : '" + e.Name + "'})");
};
})(jQuery);

$(document).ready(function() {
$('#div1').AA({ Name: 'Amin' });
$('#div2').AA({ Name: 'Reza' });
alert(JSON.stringify(arr));
});