در پست
قبلی
با مفاهیم و ویژگیهای کلی KO آشنا شدید. KO از الگوی طراحی MVVM استفاده
میکند. از آن جا که یکی از پیش نیازهای KO آشنایی اولیه با مفاهیم View و
Model است نیاز به توضیح در این موارد نیست اما اگر به هر دلیلی با این
مفاهیم آشنایی ندارید میتوانید از
اینجا
شروع کنید. اما درباره ViewModel که کمی مفهوم متفاوتی دارد، این نکته
قابل ذکر است که KO از ViewModel برای ارتباط مستقیم بین View و Model
استفاده میکند،
چیزی شبیه به منطق MVC با این تفاوت که ViewModel به جای Controller قرار
خواهد گرفت.
ابتدا باید به شرح برخی مفاهیم در KO بپردازم:
»Observable(قابل مشاهده کردن تغییرات)
KO از Observable برای ردیابی و مشاهده تغییرات خواص ViewModel استفاده
میکند. در واقع Observable دقیقا شبیه به متغیرها در JavaScript عمل
میکنند با این تفاوت که به KO اجازه میدهند که تغییرات این خواص را
پیگیری کند و این تغییرات را به بخشهای مرتبط View اعمال نماید. اما سوال
این است که KO چگونه متوجه میشود که این تغییرات بر کدام قسمت در View
تاثیر خواهند داشت؟ جواب این سوال در مفهوم Binding است.
»Binding
برای اتصال بخشهای مختلف View به Observableها باید از binding(مقید
سازی) استفاده کنیم. بدون عملیات binding، امکان اعمال تغییرات
Observableها بر روی عناصر HTML امکان پذیر نیست.
برای مثال در شکل زیر یکی از خواص ViewModel را به View متناظر مقید شده است.
با کمی دقت در شکل بالا این نکته به دست میآید که میتوان در یک ViewModel، فقط خواص مورد نظر را به عناصر Html مقید کرد.
دانلود فایلهای مورد نیاز
فایلهای مورد نیاز برای KO رو میتوانید از اینجا
دانلود نمایید و به پروژه اضافه کنید. به صورت پیش فرض فایلهای مورد
نیاز KO، در پروژههای MVC 4 وجود دارد و نیاز به دانلود آنها نیست و شما
باید فقط مراحل BundleConfig را انجام دهید.
تعریف ViewModel
برای تعریف ViewModel و پیاده سازی مراحل Observable و binding باید به صورت زیر عمل نمایید:
<html lang='en'>
<head>
<title>Hello, Knockout.js</title>
<meta charset='utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
<body>
<h1>Hello, Knockout.js</h1>
<script type='text/javascript' src='knockout-2.1.0.js'>
<script type='text/javascript'>
var personViewModel = {
firstName: "Masoud",
lastName: "Pakdel"
};
ko.applyBindings(personViewModel);
</script>
</script>
</body>
</html>
مشاهده میکنید که ابتدا یک ViewModel به نام person ایجاد کردم همراه با
دو خاصیت به نامهای firstName و lastName. تابع applyBinding برای KO بدین
معنی است که این آبجکت به عنوان یک ViewModel در این صفحه مورد استفاده
قرار خواهد گرفت. اما برای مشاهده تغییرات باید یک عنصر HTML را یه این
ViewModel مقید(bind) کنیم.
مقید سازی عناصر HTML
برای مقید سازی عناصر HTML به ViewModelها باید از data-bind attribute استفاده نماییم. برای مثال:
<p><span data-bind='text: firstName'></span>'s Shopping Cart</p>
اگر به data-bind در تگ span بالا توجه کنید خواهید دید که مقدار text در
این تگ را به خاصیت firstName در viewModel این صفحه bind شده است. تا
اینجا KO میداند که چه عنصر از DOM به کدام خاصیت از ViewModel مقید شده
است اما هنوز دستور ردیابی تغییرات(Observable) را برای KO تعیین نکردیم.
چگونه خواص را Observable کنیم
در پروژههای WPF، فقط در صورتی تغییرات خواص یک کلاس ردیابی میشوند که
اولا کلاس اینترفیس INotifyPropertyChanged را پیاده سازی کرده باشد ثانیا،
در متد set این خواص، متد OnPropertyChanged(البته این متد میتواند هر
نام دیگری نیز داشته باشد) صدا زده شده باشد.
نکته مهم و اساسی در KO نیز همین است که برای اینکه KO بتواند تغییرات هر
خاصیت را مشاهده کند حتما خواص مورد نظر باید Observable شوند. برای این
کار کافیست به صورت عمل کنید:
var personViewModel = {
firstName: ko.observable("Masoud"),
lastName: ko.observable("Pakdel")
};
مزیت اصلی برای اینکه حتما خواص مورد نظرتان Observable شوند این است که،
در صورتی که مایل نباشید تغییرات یک خاصیت بر روی View اعمال شود کافیست
از دستور بالا استفاده نکنید. درست مثل اینکه هرگز مقدار آن تغییر نکرده
است.
پیاده سازی متدهای get و set
همان طور که متوجه شدید، Observableها متغیر نیستند بلکه تابع هستند در
نتیجه برای دستیابی به مقدار یک observable کافیست آن را بدون پارامتر
ورودی صدا بزنیم و برای تغییر در مقدار آن باید همان تابع را با مقدار جدید
صدا بزنیم. برای مثال:
personViewModel.firstName() // Get
personViewModel.firstName("Masoud") // Set
البته این نکته را هم متذکر شوم که در ViewModelهای خود میتوانید توابع
سفارشی مورد نیاز را بنویسید و از آنها در جای مناسب استفاده نماید(شبیه
به مفاهیم Commandها در WPF)
مقید سازی تعاملی
اگر با WPF آشنایی دارید میدانید که در این گونه پروژهها میتوان
رویدادهای مورد نظر را به Commandهای خاص در ViewModel مقید کرد. در KO
نیز این امر به آسانی امکان پذیر است که به آن Interactive Bindings میگویند. فقط کافیست در data-bind attribute از نام رویداد استفاده نماییم.
مثال:
ایتدا بک ViewModel به صورت زیر خواهیم داشت:
function PersonViewModel() {
this.firstName = ko.observable("Masoud");
this.lastName = ko.observable("Pakdel");
this.clickMe= function() {
alert("this is test!");
};
};
تنها نکته قابل ذکر تعریف تابع سفارشی به نام clickMe است که به نوعی معادل
Command مورد نظر ما در WPF است. در عنصر HTML مورد نظر که در این جا
button است باید data-binding به صورت زیر باشد:
<button data-bind='click: clickMe'>Click Me...</button>
در نتیجه بعد از کلیک بر روی button بالا تابع مورد نظر در viewModel اجرا خواهد شد.
پس به صورت خلاصه:
- ابتدا ViewModel مورد نظر را ایجاد نمایید؛
- سپس با استفاده از data-bind عملیات مقید سازی بین View و ViewModel را انجام دهید
- در نهایت با استفاده از Obsevable تغییرات خواص مورد نظر را ردیابی نمایید.
ادامه دارد...