שמירה על קבצי mxml מסודרים על ידי שימוש ב-ViewHelpers

כמתכנתי פלקס, אנחנו עובדים המון עם קבצי mxml. קבצים אלה נועדו להוות את הview שלנו בדיוק כמו ש-html מהווים את ה-markup של דפי אינטרנט.

היות ואפליקציות פלקס מכילות לוגיקה שקשורה ל-view, לוגיקה שקשורה ל-services וכן הלאה, אני תמיד בעד לשמור דברים מסודרים ונקיים, כחלק מהעקרונות של clean code. לכן, אני מאוד אוהב שקבצי ה-mxml שלי מכילים אך ורק קוד mxml ללא קוד actionscript כלל וכלל.

איך אני עושה את זה?

אני עושה שימוש במשהו שאני קורא לו ViewHelper. אין להתבלבל אגב עם המימוש של Cairngorm ל-ViewHelper מכיוון שזה לא אותו הדבר, אני עושה שימוש ב-custom class רק כדי לשמור על קוד מאורגן ונקי.

את השיטה הזו אפשר לממש ללא קשר לפריימוורק mvc שאתם עושים בו שימוש (אני אגב משתמש ב-RobotLegs).

מה השימוש לViewHelper?

השימוש הוא בעצם לשמור את כול קוד הActionScript מחוץ לקבצי הmxml שלנו. כמו כן, ליצור משהו גנרי שאנחנו יכולים להשתמש בו דרך כול האפליקציה ושתהיה שפה משותפת. כך למשל, אפשר שהViewHelper יכיל אוסף של ולידציות שאפשר להוסיף לView, כמו כן הוא יכיל Event Listeners שקשורים לאותו View וכו'.

אוקיי, אז איך נראית אפליקציה לדוגמא?

כך נראה מבנה הקבצים שלנו בתוך Flash Builder 4

Screen shot 2010-08-19 at 5.26.08 PM

ניתן לראות שיש לנו את האקליקציה המרכזית, יש לנו View component יש לנו את ה helper של ה view component הזה ויש לנו את הקלאס BaseViewHelper שמכיל את כול השדות והפקודות שכול ViewHelper יורש מהן.

אז בואו נראה איך נראה הקוד של BaseViewHelper

אגב, מדובר בגרסא מופשטת של הקלאס, באפליקציות שלי בד"כ הקלאס הזה כולל עוד מספר דברים כמו למשל ולידציות addFieldToValidation וכדומה.

package com.kensodev.core
{
	import mx.core.UIComponent;

	public class BaseViewHelper
	{
		private var _view:UIComponent;

		public function BaseViewHelper()
		{

		}

		public function init():void
		{

		}

		public function set view(v:UIComponent):void
		{
			_view = v;
		}

		public function get view():UIComponent
		{
			return _view;
		}
	}
}

אז כמו שאפשר לראות יש לנו כאן referance לview שיכול להיות כול uiComponent וזה בערך הכול, אפשר להרחיב את הhelper לכול צורך שאתם רואים, למשל להצמיד לכול View מודל מסוים או dataProvider שצריך להיות bindable ועוד.

עכשיו, איך נראה ViewHelper שיורש מה base class שלנו?
כך


package com.kensodev.views.helpers
{
	import com.kensodev.core.BaseViewHelper;
	import com.kensodev.views.MyViewComponent;

	public class MyViewComponentHelper extends BaseViewHelper
	{
		public function MyViewComponentHelper()
		{
			super();
		}

		public function get myView():MyViewComponent
		{
			return MyViewComponent(this.view);
		}

		public override function init():void
		{
			//TODO Auto-generated method stub
			super.init();
		}

		public function myButton_clickHandler(event:MouseEvent):void
		{
			// TODO Auto-generated method stub
		}
	}
}

כמו שאפשר לראות גם כאן אני מבצע override לחלק מהפונקציות שקיימות בBase, הוספתי פונקציה שנקראת myView שמחזירה לי את ה view של הhelper אבל הפעם עם קאסטינג לview האמיתי, כך אני יכול לגשת לכול קומפוננטה על הview מתוך הhelper ישירות, זה מאוד יעיל ומרכז קוד בצורה טובה מאוד.

עכשיו לחלק האחרון, כך נראה הView שלנו

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
		   width="400"
		   height="300"
		   creationComplete="helper.init()"
		   xmlns:helper="com.kensodev.views.helpers.*">

	<mx:Script>
		<![CDATA[

		]]>
	</mx:Script>

	<helper:MyViewComponentHelper view="{this}" id="helper" />

	<mx:Button id="myButton" click="helper.myButton_clickHandler(event)"

</mx:Canvas>

כמו שאפשר לראות, אנחנו כוללים את הhelper בתוך הview מה שגורם לו להיות "מופעל", כמו כן ניתן לראות שבקליק על הכפתור אני מפעיל פונקציה בתוך הhelper במקום לכתוב את הפונקציה ישירות על אותו הקובץ

דרך אגב, יש מוסכמה על השמות, כך שבעצם קל מאוד למצוא את הקבצים האלה במערכת
אם יש לכם view שנקרא myViewComponent אז הhelper שלו יקרא myViewComponentHelper והמודל שלו יקרא myViewComponentModel והקומנד יקרא myViewComponentCommand וכן הלאה.

כך, כפי שאמרתי מאוד קל לנווט בתוך הקוד ולמצוא את הקבצים, להלן דוגמא על מה אני מדבר

Screen shot 2010-08-19 at 5.36.53 PM

קוד המקור של האפליקציה נמצא בgit, תרגישו חופשי להוריד ולראות איך זה בנוי.
http://github.com/KensoDev/view-helper-example

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

*

תגי HTML מותרים: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>