Controllers و State
State در حقیقت وضعیت حاضر نمایشی کاربر است. اینکه الان چی باید ببیند اینکه قبل تر چی دیده اینکه با کلیک بر روی فلان دکمه چه خواهد دید؟ در روشهای سنتی همه چیز با استفاده از لینک های ثابت و session کاربر قابل handle بود ولی در روشی که همه چیز سمت javascript هست چی؟ آیا به همین راحتیست؟
state را اینگونه تعریف میکنند: جوابهای متفاوتی که بر اساس یک درخواست ثابت میآید. به طور مثال یک آدرس ممکن از برای کاربر عضو یک شکل بیاید و برای کاربر غیر عضو یک شکل دیگر load شود.
در کل یک application یک state فعال دارد و لیستی از state های گذشته. ارتباط بین دو state یک transaction هست که برای حرکت در بین state ها call می شود.
باید دقت کرد تغییرات state منجر به controller میشوند و آنها عملگری را اجرا می کنند.transaction ها در این controller ها تعریف می شود. به هیچ وجه نباید دیتا هایی view ای قبلی و بعدی در html ذخیره شوند چون منجر به ازدیاد یک داده میشوند و در نهایت تغییرات مدلی نمیداند که view جدید باید ساخته شود یا html ها موجود را ویرایش کند …
قبل تر هم در بخش الگوهای طراحی controller ها را به عنوان چسب بین model و view معرفی کردیم.
چگونه یک controller پیادهسازی می شود؟ در حقیقت controller ها چیزی فراتر از یک function نیستند که باید در زمان مورد نظر اجرا شوند. یعنی map کردند change state ها و event ها به یک controller بحث است که هر کسی به گونهای پیادهسازی اش می کند.
Routing
یکی از مهمترین عوامل تغییر state یک برنامه routing است. به طور مثال آدرسهای twitter را دیدهاید به این صورت است
http://twitter.com/#!/efazati
کلاً هرچیزی بعد از شارپ (#) به سرور فرستاده نمیشود و قرار است که قسمتی که ID ی برابر این در صفحه دارد را در راس صفحه نشان دهد. برنامههای زیادی برای کنترل این وجود دارد که با تغییر url call میشوند و میتوانند transaction مربوطهاش را call کنند
این مورد در browser های زیادی compatible هست ولی برای مرورگر های قدیمی تر هم کتابخانههایی موجود است مثل:
Ben Alman » jQuery hashchange event -> http://benalman.com/projects/jquery-hashchange-plugin/
backbone.js routing
درbackbone با extend از router همانند event میشود یک سری rule جدید تعریف کرد. Transaction ها هم میتواند به صورت داخلی تعریف شود یا کار اصلی را در controller تعریف کنند.
var Workspace = Backbone.Router.extend({ routes: { "help": "help", // #help "search/:query": "search", // #search/kiwis "search/:query/p:page": "search" // #search/kiwis/p7 }, help: function() { ... }, search: function(query, page) { ... } });
همانطور که در code هم دیده میشود با یک regex با تغییر آدرس همه حالتها بررسی میشود و query هم به transaction function داده می شود.
شما میتوانید با استفاده از * هم کلاً بقیه محتوی را به transaction function بدهید. به طور مثال میخواهید آدرس فایل را به عنوان آرگومان بگیرید.
routes: { "/download/*path": "downloadFile", // <a href="http://example.com/#/download/user/images/hey.gif">Download</a> },