Skip to content

14. برنامه [SimuPaie] – نسخه ۱۰ – یک کلاینت فلکس برای سرویس وب ASP.NET

اکنون یک کلاینت فلکس برای سرویس وب ASP.NET، نسخهٔ ۵ ارائه می‌کنیم. IDE مورد استفاده، Flex Builder 3 است. نسخهٔ نمایشی این محصول را می‌توان از URL [https://www.adobe.com/cfusion/tdrc/index.cfm?loc=fr_fr&product=flex] دانلود کرد. Flex Builder 3 یک برنامهٔ مبتنی بر Eclipse است. علاوه بر این، برای اجرای کلاینت فلکس، ما از یک سرور وب آپاچی در ابزار Wamp [http://www.wampserver.com/] استفاده می‌کنیم. هر سرور آپاچی کفایت می‌کند. مرورگری که کلاینت فلکس را نمایش می‌دهد باید فلش پلیر نسخه ۹ یا بالاتر را نصب داشته باشد.

برنامه‌های فلکس از این جهت منحصر به فرد هستند که در داخل پلاگین Flash Player مرورگر اجرا می‌شوند. از این نظر، آنها شبیه به برنامه‌های Ajax هستند که اسکریپت‌ها را در صفحاتی که به مرورگر ارسال می‌شوند، جاسازی می‌کنند و سپس این اسکریپت‌ها در داخل مرورگر اجرا می‌شوند. یک برنامه فلیکس در معنای معمول یک برنامه وب نیست: این یک برنامه کلاینت برای خدماتی است که توسط سرورهای وب ارائه می‌شوند. از این نظر، مشابه یک برنامه دسکتاپ است که به عنوان کلاینت برای همان خدمات عمل می‌کند. با این حال، یک تفاوت دارد: این برنامه در ابتدا از یک سرور وب به داخل یک مرورگر مجهز به پلاگین فلش پلیر که قادر به اجرای آن است، دانلود می‌شود.

مانند یک برنامه دسکتاپ، یک برنامه فلکس عمدتاً از دو عنصر تشکیل شده است:

  • یک لایه ارائه: نماهای نمایش داده شده در مرورگر. این نماها همان غنای پنجره‌های برنامه‌های دسکتاپ را ارائه می‌دهند. یک نما با استفاده از یک زبان نشانه‌گذاری به نام MXML توصیف می‌شود.
  • یک مؤلفه کد که عمدتاً رویدادهای ناشی از اقدامات کاربر روی نما را مدیریت می‌کند. این کد همچنین می‌تواند به زبان MXML یا در یک زبان شیءگرا به نام ActionScript نوشته شود. باید بین دو نوع رویداد تمایز قائل شد:
    • رویدادهایی که نیاز به ارتباط با سرور وب دارند: پر کردن یک لیست با داده‌های ارائه‌شده توسط یک برنامه وب، ارسال داده‌های فرم به سرور و غیره. فلیکس تعدادی روش برای ارتباط با سرور به روشی که برای توسعه‌دهنده شفاف است، فراهم می‌کند. این روش‌ها به طور پیش‌فرض غیرهمزمان هستند: کاربر می‌تواند در حالی که درخواست به سرور در حال پردازش است، به تعامل با نما ادامه دهد.
    • رویدادهایی که نمای نمایش‌داده‌شده را بدون تبادل داده با سرور تغییر می‌دهند، برای مثال، کشیدن یک آیتم از یک درخت و رها کردن آن در یک لیست. این نوع رویداد به طور کامل به صورت محلی در داخل مرورگر مدیریت می‌شود.

یک برنامه فلکس اغلب به شکل زیر اجرا می‌شود:

  • در [1]، یک صفحه HTML درخواست می‌شود
  • در [2]، آن ارسال می‌شود. این شامل یک فایل باینری SWF (فلش ShockWave) است که کل برنامه Flex را در خود جای داده است: تمام نماها و کدهای رسیدگی به رویدادهای آن‌ها. این فایل توسط افزونه Flash Player مرورگر اجرا خواهد شد.
  • کلاینت Flex به صورت محلی در داخل مرورگر اجرا می‌شود، مگر زمانی که به داده‌های خارجی نیاز داشته باشد. در چنین مواردی، این داده‌ها را از سرور [3] درخواست می‌کند. این فایل داده‌ها را در [4] در قالب‌های مختلف دریافت می‌کند: XML یا باینری. برنامه‌ای که روی سرور وب پرس‌وجو می‌شود می‌تواند به هر زبانی نوشته شود. تنها چیزی که اهمیت دارد، فرمت پاسخ است.

ما معماری اجرایی یک برنامه فلکس را به گونه‌ای توصیف کرده‌ایم که خواننده بتواند تفاوت آن را با معماری یک برنامه وب متعارف درک کند، جایی که صفحات کد (جاوااسکریپت، فلکس، سیلورلایت و غیره) را که مرورگر آن را اجرا کند، در خود جای نمی‌دهند. در مورد دوم، مرورگر منفعل است: آن صرفاً صفحات HTML تولیدشده روی سرور وب را نمایش می‌دهد، که سرور آن‌ها را برای مرورگر ارسال می‌کند.

14.1. معماری برنامه‌های کلاینت/سرور

معماری کلاینت/سرور پیاده‌سازی‌شده مشابه معماری نسخه‌های ۶ و ۸ است:

در [1]، لایه وب ASP.NET با یک لایه وب Flex که به زبان‌های MXML و ActionScript نوشته شده است، جایگزین می‌شود. کلاینت [C] توسط Flex Builder IDE تولید خواهد شد. در اینجا باید توجه داشت که این معماری شامل دو سرور وب است که نشان داده نشده‌اند:

  • یک سرور وب ASP.NET که سرویس وب [S] را اجرا می‌کند
  • یک سرور وب APACHE که کلاینت وب [1] را اجرا می‌کند

14.2. پروژه Flex 3 کلاینت

ما کلاینت فلکس را با استفاده از Flex Builder 3 (IDE) می‌سازیم:

  • در Flex Builder 3، ما یک پروژه جدید در [1] ایجاد می‌کنیم
  • در [2] برای آن نامی انتخاب می‌کنیم و در [3] مشخص می‌کنیم که در کدام پوشه ایجاد شود
  • در [4]، به برنامهٔ اصلی (همان که اجرا خواهد شد) یک نام بدهید
  • در [5]، پس از تولید پروژه
  • در [6]، فایل اصلی برنامه MXML
  • فایلی به نام MXML حاوی یک ویو و کد مربوط به پردازش رویدادهای آن است. زبانه [Source] [7] دسترسی به فایل MXML را فراهم می‌کند. این فایل حاوی برچسب‌های <mx> است که نما را توصیف می‌کنند و همچنین کد ActionScript.
  • این نما را می‌توان به‌صورت گرافیکی با استفاده از برگه‌های [Design] و [8] ایجاد کرد. سپس برچسب‌های MXML که نما را توصیف می‌کنند، به‌طور خودکار در برگه [Source] تولید می‌شوند. معکوس آن نیز صادق است: برچسب‌های MXML که مستقیماً به برگه [Source] اضافه می‌شوند، به‌صورت گرافیکی در برگه [Design] منعکس می‌شوند.

14.3. نما شمارهٔ ۱

ما به‌تدریج یک رابط وب مشابه نسخهٔ ۱ را خواهیم ساخت (رجوع شود به بند ۴). ابتدا، رابط زیر را خواهیم ساخت:

  • در [1]، نمایی از زمانی که اتصال به سرویس وب با موفقیت برقرار شد. سپس فهرست کشویی کارمند پر می‌شود.
  • در [2]، نمایی از زمانی که اتصال به سرویس وب برقرار نشد. سپس یک پیام خطا نمایش داده می‌شود.

فایل اصلی کلاینت، [main.xml]، به شرح زیر است:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
    creationComplete="init()">
    <mx:VBox width="100%">
        <mx:Label text="Feuille de salaire" fontSize="30"/>
        <mx:HBox>
            <mx:VBox>
                <mx:Label text="Employés"/>
                <mx:ComboBox id="cmbEmployes" dataProvider="{employes}" labelFunction="displayEmploye"/>
            </mx:VBox>
            <mx:VBox>
                <mx:Label text="Heures travaillées"/>
                <mx:TextInput id="txtHeuresTravaillees"/>
            </mx:VBox>
            <mx:VBox>
                <mx:Label text="Jours travaillés"/>
                <mx:NumericStepper id="joursTravailles" minimum="0" maximum="31" stepSize="1"/>
            </mx:VBox>
            <mx:VBox>
                <mx:Label text=""/>
                <mx:Button id="btnSalaire" label="Salaire"/>
            </mx:VBox>
        </mx:HBox>
        <mx:TextArea id="msg" minWidth="400" minHeight="100" editable="false" visible="true" enabled="true" horizontalScrollPolicy="auto" verticalScrollPolicy="auto" x="0" y="0" maxHeight="100" maxWidth="400"/>        
    </mx:VBox>

    <mx:WebService ...>
        ...
    </mx:WebService>

    <mx:Script>
        <![CDATA[
...    
            // داده‌ها
            [Bindable]
            private var employes : ArrayCollection;

            private function init():void{
...
            }
        ]]>
    </mx:Script>
</mx:Application>

در این کد، چندین عنصر باید از هم متمایز شوند:

  • تعریف برنامه (خطوط ۲–۳)
  • توضیح نمای برنامه (خطوط ۴–۲۵)
  • پردازشگرهای رویداد در زبان ActionScript درون تگ <mx:Script> (خطوط ۳۱–۴۲)
  • تعریف سرویس وب راه دور (خطوط 27–29)

بیایید با اظهار نظر در مورد تعریف خودِ برنامه و توصیف نمای آن شروع کنیم:

  • خطوط ۲–۳: تعریف:
    • چیدمان اجزا در داخل کانتینر نما. ویژگی layout="vertical" مشخص می‌کند که اجزا به‌صورت پشت سر هم چیده شوند.
    • متدی که پس از نمونه‌سازی همهٔ اجزای نما اجرا می‌شود: c.a.d. نقطه‌ای که در آن همهٔ اجزای آن نمونه‌سازی شده‌اند. ویژگی creationComplete="init();" نشان می‌دهد که متد init در خط ۳۸ باید اجرا شود. creationComplete یکی از رویدادهایی است که کلاس Application می‌تواند صادر کند.
  • خطوط ۴–۲۵ کامپوننت‌های نما را تعریف می‌کنند
  • خطوط ۴–۲۵: یک کانتینر عمودی: اجزا یکی زیر دیگری قرار خواهند گرفت
  • خط ۵: یک فیلد متنی را تعریف می‌کند
  • خطوط ۶–۲۳: یک کانتینر افقی: اجزا به‌صورت افقی درون آن قرار خواهند گرفت.
  • خطوط ۷–۱۰: یک کانتینر عمودی که یک فیلد متن و یک لیست کشویی را در خود جای خواهد داد
  • خط ۸: متن
  • خط ۹: لیست کشویی که لیست کارمندان در آن قرار خواهد گرفت. تگ dataProvider="{employees}" منبع داده‌ها برای پر کردن لیست را مشخص می‌کند. در اینجا، لیست با شیء employes که در خط ۳۶ تعریف شده است، پر خواهد شد. برای نوشتن dataProvider="{employees}"، فیلد employes باید دارای ویژگی [Bindable] (خط ۳۵) باشد. این ویژگی اجازه می‌دهد متغیر ActionScript خارج از تگ <mx:Script> ارجاع داده شود. میدان employes از نوع ArrayCollection است، نوعی از ActionScript که امکان ذخیره لیست اشیاء را فراهم می‌کند؛ در این مورد، لیستی از اشیاء از نوع Employe.
  • خطوط ۱۱–۱۴: یک کانتینر عمودی که متن و یک فیلد ورودی را در خود جای خواهد داد
  • خط ۱۲: متن
  • خط ۱۳: فیلد ورودی برای ساعات کاری.
  • خطوط ۱۵–۱۸: یک کانتینر عمودی که شامل متن و یک شمارشگر خواهد بود
  • خط ۱۶: متن
  • خط ۱۷: شمارنده برای وارد کردن تعداد روزهای کاری
  • خطوط ۱۹–۲۲: یک کانتینر عمودی که شامل متن و دکمه‌ای است که محاسبه حقوق فرد انتخاب‌شده از فهرست کشویی را انجام می‌دهد.
  • خط ۲۰: متن
  • خط ۲۱: دکمه.
  • خط ۲۳: پایان کانتینر افقی که در خط ۶ شروع شده بود
  • خط 24: یک کادر متن درون یک کامپوننت از نوع TextArea. این کادر پیام‌های خطا را نمایش خواهد داد.
  • خط ۲۵: پایان کانتینر عمودی که در خط ۴ شروع شده است

خطوط ۴ تا ۲۵ نمای زیر را در برگه [Design] تولید می‌کنند:

  • [1]: تولید شده توسط کامپوننت Label در خط ۵
  • [2]: توسط کامپوننت ComboBox در خط ۹ تولید شد
  • [3]: توسط کامپوننت TextInput در خط 13 تولید شد
  • [4]: توسط کامپوننت NumericStepper در خط 17 تولید شد
  • [5]: توسط کامپوننت Button در خط 21 تولید شد
  • [6]: توسط کامپوننت TextArea در خط ۲۴ تولید شد

اکنون بیایید اعلان سرویس وب راه دور را بررسی کنیم:


<mx:WebService id="pam"
        wsdl="http://localhost:1077/Service1.asmx?WSDL" 
        fault="wsFault(event);" 
        showBusyCursor="true">
        <mx:operation 
            name="GetAllIdentitesEmployes" 
            result="loadEmployesCompleted(event)" 
            fault="loadEmployesFault(event);">
            <mx:request/>
        </mx:operation>
    </mx:WebService>

  • خط ۱: سرویس وب یک کامپوننت با شناسه‌ی pam (ویژگی id) است
  • خط ۲: URI از فایل WSDL سرویس وب (رجوع کنید به بخش ۹.۲)
  • خط ۳: متدی که در صورت بروز خطا در حین ارتباط با سرویس وب اجرا می‌شود: متد wsFault.
  • خط ۴: درخواست نمایش یک نشانگر برای اطلاع کاربر از در حال انجام بودن تبادل با سرویس وب.
  • خطوط ۵–۱۰: یکی از عملیات ارائه‌شده توسط سرویس وب راه دور. در اینجا، متد GetAllIdentitesEmployes.
  • خط ۷: متدی که باید هنگام موفقیت‌آمیز بودن فراخوانی این متد اجرا شود، c.a.d. این زمانی است که سرویس وب با موفقیت فهرست کارمندان را بازمی‌گرداند
  • خط ۸: متدی که در صورت پایان فراخوانی این متد با خطا اجرا شود.
  • خط ۹: پارامترها برای عملیات GetAllIdentitesEmployes. می‌دانیم که این متد هیچ پارامتری را انتظار ندارد. بنابراین، تگ <mx:request> را خالی می‌گذاریم.

اکنون بیایید کد ActionScript مرتبط با سرویس وب را بررسی کنیم:


<mx:Script>
        <![CDATA[
            import mx.rpc.events.FaultEvent;
            import mx.collections.ArrayCollection;
            import mx.rpc.events.ResultEvent;
                        
            // داده‌ها
            [Bindable]
            private var employes : ArrayCollection;
    
            private function init():void{
                // توجه به جزئیات فیلد پیام
                msgHeight=msg.height;
                msgWidth=msg.width;
                //مخفی کردن ناحیه پیام
                hideMsg();
                //ارسال درخواست به سرویس وب راه دور برای بازیابی فهرست ساده‌شده کارمندان
                pam.GetAllIdentitesEmployes.send();
            }
            
            private function wsFault(event:Event):void{
                    // گزارش خطا
                    msg.text="Service distant indisponible";
                    showMsg();
            }
            
            private function loadEmployesCompleted(event:ResultEvent):void{
                // پر کردن لیست کشویی کارمندان
                employes=event.result as ArrayCollection;
            }
            
            private function displayEmploye(employe:Object):String{
                //شناسه کارمند
                return employe.Prenom + " " + employe.Nom;
            }
            
            private function loadEmployesFault(event:FaultEvent):void{
                // نمایش پیام خطا
                msg.text=event.fault.message;
                // فرم
                showMsg();
            }

    // مدیریت بلوک
        private var msgWidth:int;
        private var msgHeight:int;
        
        private function hideMsg():void{
            msg.height=0;
            msg.width=0;
        }
        
        private function showMsg():void{
            msg.height=msgHeight;
            msg.width=msgWidth;
        }
        
      
        ]]>
    </mx:Script>
  • خط ۱۱: متد init هنگام شروع برنامه اجرا می‌شود زیرا ما نوشته‌ایم:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
    creationComplete="init()">
  • خطوط ۱۳–۱۴: ارتفاع و عرض ناحیه پیام ذخیره می‌شوند. دو متد برای پنهان یا نمایش ناحیه پیام استفاده می‌شوند: hideMsg (خطوط ۴۸–۵۱) و showMsg (خطوط ۵۳–۵۶)، بسته به اینکه خطایی رخ داده باشد یا خیر. متد hideMsg با تنظیم ارتفاع و عرض ناحیه پیام روی 0، آن را مخفی می‌کند. متد showMsg با بازیابی ارتفاع و عرض ذخیره‌شده در متد init، ناحیه پیام را نمایش می‌دهد.
  • خط ۱۶: ناحیه پیام پنهان می‌شود. در ابتدا، هیچ خطایی وجود ندارد.
  • خط ۱۸: متد GetAllIdentitesEmploye (خط ۶ سرویس وب) از سرویس وب pam (خط ۱ سرویس وب) فراخوانی می‌شود. این فراخوانی ناهمزمان است. خط ۷ سرویس وب مشخص می‌کند که متد loadEmployesCompleted در صورتی که این فراخوانی غیرهمزمان با موفقیت به پایان برسد، اجرا خواهد شد. خط ۸ سرویس وب مشخص می‌کند که متد loadEmployesFault در صورتی که این فراخوانی غیرهمزمان با شکست مواجه شود، اجرا خواهد شد.
  • خط ۲۷: متد loadEmployesCompleted، که در صورت موفقیت‌آمیز بودن فراخوانی سرویس وب در خط ۱۸ اجرا می‌شود.
  • خط ۲۹: می‌دانیم که سرویس وب پاسخی با کد XML بازمی‌گرداند. ارزش دارد به این مورد بازگردیم تا کد ActionScript را درک کنیم:
  • به [1]، صفحه سرویس وب [Service.asmx]
  • به [2]، لینک صفحه آزمایش برای متد [GetAllIdentitesEmployes]
  • به [3]، تست کامل است. هیچ پارامتری مورد انتظار نیست.
  • در [4]: پاسخ XML شامل آرایه‌ای از کارمندان است. برای هر یک از آن‌ها، پنج مورد اطلاعات در تگ‌های <Id>، <Version>، <SS>، <Nom> و <Prenom> گنجانده شده است. اگر پاسخ XML در آرایه‌ای از نوع ArrayCollection به نام employes قرار گیرد:
    • employes.getItemAt(i): عنصر شمارهٔ i از آرایه است
    • employes.getItemAt(i). SS: شماره بیمه ملی این کارمند است.
    • employes.getItemAt(i).Name: نام این کارمند است
    • ...

بیایید به کد ActionScript بازگردیم:

  • خط ۲۹: event.result نمایانگر پاسخ سرویس وب XML است. متد GetAllIdentitesEmployes یک آرایه از کارمندان را بازمی‌گرداند. event.result این آرایه از کارمندان را نشان می‌دهد. این مقدار در یک متغیر از نوع ArrayCollection ذخیره می‌شود، نوعی که عموماً نمایانگر مجموعه‌ای از اشیاء است. این متغیر با نام employes در خط 9 تعریف شده است. به یاد داشته باشید که این متغیر منبع داده برای لیست کشویی کارمندان است:

<mx:ComboBox id="cmbEmployes" dataProvider="{employes}" labelFunction="displayEmploye"/>

برای هر کارمند در منبع داده‌های آن، لیست کشویی متد displayEmploye (ویژگی labelFunction) را برای نمایش کارمند فراخوانی می‌کند. خطوط ۳۲ تا ۳۴ نشان می‌دهند که این متد نام و نام خانوادگی کارمند را نمایش می‌دهد.

  • خط ۳۷: متد loadEmployesFault که در صورت شکست فراخوانی سرویس وب در خط ۱۸ اجرا می‌شود. event.fault.message پیام خطایی است که توسط سرویس وب بازگردانده می‌شود.
  • خط ۳۹: این پیام خطا در فیلد پیام قرار می‌گیرد
  • خط ۴۱: کادر پیام نمایش داده می‌شود.

پس از ساخت برنامه، کد اجرایی آن در پوشه [bin-debug] پروژه Flex قرار دارد:

بالا،

  • فایل [main.html] نمایانگر فایل HTML است که مرورگر برای دریافت کلاینت فلکس از سرور وب درخواست می‌کند
  • فایل [main.swf] باینری کلاینت فلکس است که در صفحه HTML که به مرورگر ارسال می‌شود، جاسازی شده و سپس توسط افزونه Flash Player مرورگر اجرا می‌شود.

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

سمت سرور:

  • سرویس وب ASP.NET را راه‌اندازی کنید [S]

سمت کلاینت:

  • سرور آپاچی را راه‌اندازی کنید، که برای ارائهٔ برنامهٔ فلکس درخواست خواهد شد.

در اینجا از ابزار Wamp استفاده می‌کنیم. با این ابزار می‌توانیم یک نام مستعار (alias) را به پوشه [bin-debug] در پروژه Flex مرتبط کنیم.

  • آیکون Wamp در پایین صفحه [1] قرار دارد
  • روی آیکون Wamp کلیک چپ کرده و گزینه Apache را انتخاب کنید [2] / مسیرهای مستعار [3, 4]
  • گزینه [5]: افزودن یک نام مستعار را انتخاب کنید
  • در [6]، یک نام مستعار (هر نامی) برای برنامه وبی که قرار است اجرا شود، وارد کنید
  • در [7]، دایرکتوری ریشهٔ برنامهٔ وبی را که از این نام مستعار استفاده خواهد کرد، مشخص کنید: این پوشهٔ [bin-debug] پروژهٔ Flex است که همین حالا ساخته‌ایم.

بیایید ساختار پوشه [bin-debug] برای پروژه Flex را مرور کنیم:

فایل [main.html] همان فایل HTML از برنامه Flex است. به لطف نام مستعار (alias) که همین حالا برای پوشه [bin-debug] ایجاد کرده‌ایم، می‌توان به این فایل از طریق URL و [http://localhost/pam-v10-flex-client-webservice/main.html] دسترسی داشت. می‌توانیم آن را در یک مرورگر با افزونه Flash Player نسخه ۹ یا بالاتر مشاهده کنیم:

  • در [1]، URL از برنامه Flex
  • به [2]، لیست کشویی کارکنان زمانی که همه چیز به درستی کار می‌کند
  • به [3]، نتیجه‌ی به‌دست‌آمده هنگام متوقف‌شدن سرویس وب

ممکن است بخواهید کد منبع صفحه HTML دریافتی را مشاهده کنید:

<!-- ذخیره شده از url=(0014)about:internet -->
<html lang="en">

<!-- 
Smart developers always View Source. 

This application was built using Adobe Flex, an open source framework
for building rich Internet applications that get delivered via the
Flash Player or to desktops via Adobe AIR. 

Learn more about Flex at http://flex.org 
// -->

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<!--   BEGIN بخش مورد نیاز تاریخچه مرورگر -->
<link rel="stylesheet" type="text/css" href="history/history.css" />
<!--   END بخش تاریخچه مرورگر الزامی -->

<title></title>
....
</head>

<body scroll="no">
...
<noscript>
        <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
                        id="main" width="100%" height="100%"
                        codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
                        <param name="movie" value="main.swf" />
                        <param name="quality" value="high" />
                        <param name="bgcolor" value="#869ca7" />
                        <param name="allowScriptAccess" value="sameDomain" />
                        <embed src="main.swf" quality="high" bgcolor="#869ca7"
                                width="100%" height="100%" name="main" align="middle"
                                play="true"
                                loop="false"
                                quality="high"
                                allowScriptAccess="sameDomain"
                                type="application/x-shockwave-flash"
                                pluginspage="http://www.adobe.com/go/getflashplayer">
                        </embed>
        </object>
</noscript>
</body>
</html>
  • بدنهٔ صفحه از خط ۲۵ آغاز می‌شود. این شامل HTML استاندارد نیست، بلکه یک شیء (خط ۲۸) از نوع "application/x-shockwave-flash" (خط ۴۱) است. این فایل [main.swf] (خط ۳۱) است که می‌توان آن را در پوشه [bin-debug] پروژه Flex یافت. این یک فایل بزرگ است: تقریباً ۶۰۰ کیلوبایت برای این مثال ساده.

14.4. نما شماره ۲

ما قصد داریم یک کانtejner جدید از نوع VBox به نمای فعلی اضافه کنیم:

  • در [4,5]، ما [main2.mxml] را به عنوان برنامه پیش‌فرض جدید تنظیم می‌کنیم. این همان چیزی است که اکنون کامپایل خواهد شد.
  • در [6]، برنامهٔ پیش‌فرض با یک نقطهٔ آبی نشان داده می‌شود.

کانتینر [1] اطلاعات مربوط به کارمند انتخاب‌شده در لیست کشویی [2] را نمایش خواهد داد. ما [main.xml] را به صورت [main2.xml] و [3] کپی می‌کنیم تا نمای جدید را بسازیم. اکنون با [main2.xml] کار خواهیم کرد.

تغییر ایجاد شده در پروژه قبلی، افزودن کانtejner در خط ۲۶ بالا است که حاوی کد MXML از کانtejner [1] نما است. ما شناسه employe را به آن اختصاص می‌دهیم تا بتوانیم از طریق کد آن را دستکاری کنیم. این کانتینر باید بتواند با استفاده از همان تکنیکی که قبلاً برای ناحیه پیام به کار رفت، پنهان یا نمایش داده شود.

بیایید به رابط کاربری ویو بازگردیم:

بیایید کانتینرهای مختلف برای اطلاعات جدید نمایش‌داده‌شده را شناسایی کنیم:

  • V1: کانتینر عمودی برای همهٔ مؤلفه‌ها: برچسب Employé، [1] و کانتینرهای افقی [H1] و [H2]
  • H1: کانتینر افقی برای اطلاعات Nom، Prénom، Adresse
  • V2: کانتینر عمودی برای برچسب Nom و نمایش نام کارمند.
  • H2: کانتینر افقی برای اطلاعات Ville، کد پستی، Indice

کد کامل برای کانتینر "employe" به شرح زیر است:


<mx:VBox id="employe" width="100%">
        <mx:Label text="Employé" fontSize="20" color="#09F3EB"/>
        <mx:HBox>
        <mx:VBox >
            <mx:Label text="Nom"/>
            <mx:VBox backgroundColor="#EECA05">
            <mx:Text id="lblNom" minWidth="100" minHeight="20" fontFamily="Verdana" textAlign="center"/>
            </mx:VBox>
        </mx:VBox>
        <mx:VBox >
            <mx:Label text="Prénom"/>
            <mx:VBox backgroundColor="#EECA05">
            <mx:Text id="lblPreNom" minWidth="100" minHeight="20" fontFamily="Verdana" textAlign="center"/>
            </mx:VBox>
        </mx:VBox>
        <mx:VBox >
            <mx:Label text="Adresse"/>
            <mx:VBox backgroundColor="#EECA05">
            <mx:Text id="lblAdresse" minWidth="250" minHeight="20" fontFamily="Verdana" textAlign="center"/>
            </mx:VBox>
        </mx:VBox>
        </mx:HBox>
        <mx:HBox>
        <mx:VBox >
            <mx:Label text="Ville"/>
            <mx:VBox backgroundColor="#EECA05">
            <mx:Text id="lblVille" minWidth="100" minHeight="20" fontFamily="Verdana" textAlign="center"/>
            </mx:VBox>
        </mx:VBox>
        <mx:VBox >
            <mx:Label text="Code Postal"/>
            <mx:VBox backgroundColor="#EECA05">
            <mx:Text id="lblCodePostal" minWidth="70" minHeight="20" fontFamily="Verdana" textAlign="center"/>
            </mx:VBox>
        </mx:VBox>
        <mx:VBox >
            <mx:Label text="Indice"/>
            <mx:VBox backgroundColor="#EECA05">
            <mx:Text id="lblIndice" minWidth="20" minHeight="20" fontFamily="Verdana" textAlign="center"/>
            </mx:VBox>
        </mx:VBox>
        </mx:HBox>
    </mx:VBox>

کد به‌خودی‌خود گویا است. بیایید فقط نمایش‌دهندهٔ افقی که نام کارمند را نمایش می‌دهد را توضیح دهیم، برای مثال:

  • خطوط ۴–۹: کانتینر عمودی
  • خط ۵: برچسب Nom
  • خطوط ۶–۸: یک کانتینر عمودی که نام کارمند را نمایش می‌دهد (خط ۷). ما می‌خواهیم رنگ پس‌زمینه‌ی متفاوتی برای فیلدهایی که اطلاعات مربوط به کارمند را نمایش می‌دهند، تعیین کنیم. کامپوننت Text این گزینه را ارائه نمی‌دهد (یا شاید من به درستی بررسی نکرده‌ام). امکان تعیین رنگ پس‌زمینه‌ی یک کانتینر وجود دارد. به همین دلیل از آن در اینجا استفاده شده است.
  • خط ۷: کامپوننت Text که نام کارمند را نمایش می‌دهد. ما برای آن حداقل ارتفاع و عرض را تعیین کرده‌ایم.

ما از کانتینر «employe» برای نمایش جزئیات کارمند که توسط کاربر از لیست کشویی کارمندان انتخاب شده است، استفاده خواهیم کرد؛ این کار به طور مستقل از دکمه «[Salaire]» انجام می‌شود، دکمه‌ای که پس از وارد شدن تمام اطلاعات لازم، برای محاسبه حقوق به کار گرفته خواهد شد.

برای مدیریت تغییرات در انتخاب لیست کشویی «employes»، کد آن «MXML» به شرح زیر تغییر می‌کند:


<mx:ComboBox id="cmbEmployes" dataProvider="{employes}" labelFunction="displayEmploye" change="displayInfosEmploye();"/>

رویداد 'change' توسط لیست کشویی زمانی که کاربر انتخاب خود را تغییر می‌دهد، فعال می‌شود. دست‌پردازنده این رویداد متد displayInfosEmploye خواهد بود.

بیایید متدهای ارائه شده توسط سرویس وب راه دور را به یاد بیاوریم:


    // فهرست تمام هویت‌های کارکنان 
    public Employe[] GetAllIdentitesEmployes();
    // ------- محاسبه حقوق 
public FeuilleSalaire GetSalaire(string ss, double heuresTravaillees, int joursTravailles);

در اینجا، می‌خواهیم جزئیات (نام خانوادگی، نام، و غیره) کارمند انتخاب‌شده در لیست کشویی را نمایش دهیم. سرویس وب متدی برای بازیابی این اطلاعات ارائه نمی‌دهد. با این حال، می‌توانیم با ارسال شماره SS کارمند انتخاب‌شده و مقدار 0 برای ساعات و روزهای کاری، از متد GetSalaire استفاده کنیم. یک محاسبه حقوق تکراری انجام خواهد شد، اما متد GetSalaire یک شیء از نوع FeuilleSalaire بازخواهد گرداند که در آن اطلاعات مورد نیاز ما را پیدا خواهیم کرد.

اعلامیه‌ی سرویس وب فعلی اصلاح می‌شود تا تعریف متد GetSalaire را شامل شود:


<mx:WebService id="pam"
        wsdl="http://localhost:1077/Service1.asmx?WSDL" 
        fault="wsFault(event);" 
        showBusyCursor="true">
        <mx:operation 
            name="GetAllIdentitesEmployes" 
            result="loadEmployesCompleted(event)" 
            fault="loadEmployesFault(event);">
            <mx:request/>
        </mx:operation>
        <mx:operation name="GetSalaire" 
            result="getSalaireCompleted(event)"
            fault="getSalaireFault(event);">
            <mx:request>
                <ss>{employes.getItemAt(cmbEmployes.selectedIndex).SS}</ss>
              <heuresTravaillees>{heuresTravaillees}</heuresTravaillees>
              <joursTravailles>{joursDeTravail}</joursTravailles>
            </mx:request>
        </mx:operation>
</mx:WebService>
  • خطوط ۱۱–۱۹: تعریف متد GetSalaire سرویس وب
  • خط ۱۲: متدی را تعریف می‌کند که در صورت موفقیت تماس با متد GetSalaire اجرا شود
  • خط ۱۳: متدی را تعریف می‌کند که در صورت ناموفق بودن فراخوانی متد GetSalaire اجرا شود
  • خطوط 14–18: متد GetSalaire سه پارامتر را انتظار دارد. این پارامترها درون تگ <mx:request> به شکل <param1>value1</param1> تعریف می‌شوند. شناسه param1 نمی‌تواند دلخواه باشد. شما باید از نام‌های مورد انتظار سرویس وب استفاده کنید:
  • در [1]، صفحه سرویس وب [http://localhost:1077/Service1.asmx]
  • به [2]، لینک به صفحه آزمایشی برای متد [GetSalaire]
  • در [3]، پارامترهای مورد انتظار متد. این‌ها اسامی هستند که باید به‌عنوان تگ‌های فرزند تگ <mx:request> استفاده شوند.

بیایید به اعلان سرویس وب بازگردیم:


        <mx:operation name="GetSalaire" 
            result="getSalaireCompleted(event)"
            fault="getSalaireFault(event);">
            <mx:request>
                <ss>{employes.getItemAt(cmbEmployes.selectedIndex).SS}</ss>
              <heuresTravaillees>{heuresTravaillees}</heuresTravaillees>
              <joursTravailles>{joursDeTravail}</joursTravailles>
            </mx:request>
        </mx:operation>
  • خط ۵: پارامتر ss. به یاد داشته باشید که وقتی برنامه Flex اجرا شد، آرایهٔ تمام کارمندان در متغیری به نام `employes` از نوع ArrayCollection ذخیره شد.
    • employes.getItemAt(i): شماره کارمند i در آرایه است
    • employes.getItemAt(i).SS: شماره تأمین اجتماعی این کارمند است.
    • cmbEmployes.selectedIndex: شماره آیتمی است که از لیست کشویی کارمندان cmbemployes انتخاب شده است.

در مثال بالا، چگونه می‌توانیم بفهمیم که SS شماره تأمین اجتماعی یک کارمند است؟ برای این کار، باید به پاسخی که توسط متد GetAllIdentitesEmployes بازگردانده شده است، مراجعه کنیم:

  • در [1]، صفحه سرویس وب [Service.asmx]
  • به [2]، لینک صفحه آزمایش برای متد [GetAllIdentitesEmployes]
  • به [3]؛ تست کامل است. هیچ پارامتری انتظار نمی‌رود.
  • در [4]: پاسخ XML شامل آرایه‌ای از کارمندان است. این آرایه در متغیر employes ذخیره شده است. می‌توانیم در [5] ببینیم که SS در واقع تگی است که برای نگهداری شماره بیمه ملی استفاده می‌شود.

بیایید بررسی خود را از سرویس وب به پایان برسانیم:


        <mx:operation name="GetSalaire" 
            result="getSalaireCompleted(event)"
            fault="getSalaireFault(event);">
            <mx:request>
                <ss>{employes.getItemAt(cmbEmployes.selectedIndex).SS}</ss>
              <heuresTravaillees>{heuresTravaillees}</heuresTravaillees>
              <joursTravailles>{joursDeTravail}</joursTravailles>
            </mx:request>
</mx:operation>
  • خط ۶: تعداد ساعات کاری توسط متغیر heuresTravaillees ارائه خواهد شد
  • خط ۶: تعداد روزهای کاری توسط متغیر joursDeTravail ارائه خواهد شد

این متغیرها باید در داخل تگ <mx:Script> با استفاده از ویژگی [Bindable] اعلام شوند، که این امکان را برای ارجاع به آنها توسط اجزای MXML (خطوط ۷–۱۰ زیر) فراهم می‌کند.


    <mx:Script>
        <![CDATA[
...
            // داده‌ها
            [Bindable]
            private var employes : ArrayCollection;
            [Bindable]
            private var heuresTravaillees:Number;
            [Bindable]
            private var joursDeTravail:int;
...
</mx:Script>

کد مدیریت رویداد برای نما به شرح زیر تغییر می‌کند:


<mx:Script>
        <![CDATA[
            import mx.rpc.events.FaultEvent;
            import mx.collections.ArrayCollection;
            import mx.rpc.events.ResultEvent;
                        
            // داده‌ها
            [Bindable]
            private var employes : ArrayCollection;
            [Bindable]
            private var heuresTravaillees:Number;
            [Bindable]
            private var joursDeTravail:int;
    
            private function init():void{
                // ثبت ارتفاع و عرض # بلوک‌ها
                employeHeight=employe.height;
                employeWidth=employe.width;
                // پنهان کردن برخی عناصر
                hideEmploye();
...
            }
            
            private function displayInfosEmploye():void{
                // فرم
                hideEmploye();
                // محاسبهٔ حقوق فرضی
                heuresTravaillees=0;
                joursDeTravail=0;
                pam.GetSalaire.send();
            }
            
            private function getSalaireCompleted(event:ResultEvent):void{
    ...
            }
            
            private function getSalaireFault(event:FaultEvent):void{
    ...
            }

        // نماهای جزئی -------------------------------------------------
        private var employeHeight:int;
        private var employeWidth:int;
        
        private function hideEmploye():void{
            employe.height=0;
            employe.width=0;
        }
        
        private function showEmploye():void{
            employe.height=employeHeight;
            employe.width=employeWidth;
        }
        ]]>
    </mx:Script>
  • خط ۱۵: متد init که هنگام راه‌اندازی برنامه Flex اجرا می‌شود، ارتفاع و عرض کانتینر عمودی employe را ذخیره می‌کند تا پس از پنهان شدن (خطوط ۴۵–۴۸)، قابل بازیابی باشد (خطوط ۵۰–۵۳).
  • خط ۲۴: متد displayInfosEmploye متدی است که هنگام تغییر انتخاب کاربر در لیست کشویی کارمندان اجرا می‌شود.
  • خط ۲۶: کانتینر employe در صورتی که قبلاً قابل مشاهده بوده، پنهان می‌شود
  • خط ۳۰: متد سرویس وب GetSalaire به‌صورت غیرهمزمان فراخوانی می‌شود. می‌دانیم که این متد سه پارامتر انتظار دارد:

                <ss>{employes.getItemAt(cmbEmployes.selectedIndex).SS}</ss>
              <heuresTravaillees>{heuresTravaillees}</heuresTravaillees>
              <joursTravailles>{joursDeTravail}</joursTravailles>
  • خط ۱: پارامتر `ss` برابر با شناسه `SS` کارمندی خواهد بود که از لیست کشویی کارمندان انتخاب شده است
  • خط ۲: متد displayInfosEmploye متغیر heuresTravaillees را روی ۰ تنظیم می‌کند (خط ۲۸)
  • خط ۳: متد displayInfosEmploye مقدار 0 را به متغیر joursDeTravail (خط ۲۹) اختصاص می‌دهد

روش GetSalaireCompleted در صورتی اجرا می‌شود که روش سرویس وب GetSalaire با موفقیت به پایان برسد:


private function getSalaireCompleted(event:ResultEvent):void{
                // پنهان کردن پیام خطا
                hideMsg();
                // یک برگه پرداخت دریافت می‌شود
                var feuilleSalaire:Object=event.result;
                // نمایش
                lblNom.text=feuilleSalaire.Employe.Nom;
                lblPreNom.text=feuilleSalaire.Employe.Prenom;
                lblAdresse.text=feuilleSalaire.Employe.Adresse;
                lblVille.text=feuilleSalaire.Employe.Ville;
                lblCodePostal.text=feuilleSalaire.Employe.CodePostal;
                lblIndice.text=feuilleSalaire.Employe.Indice;
                showEmploye();
            }
  • خط ۳: ناحیه پیام در صورت نمایش پنهان می‌شود.
  • خط ۵: برگه پرداخت بازگردانده‌شده توسط متد GetSalaire بازیابی می‌شود

برای اینکه دقیقاً بفهمیم متد GetSalaire چه چیزی را برمی‌گرداند، به صفحه سرویس وب بازمی‌گردیم:

  • به [1]، صفحه سرویس وب [Service.asmx]
  • به [2]، پیوندی که به صفحه آزمایشی برای روش [GetSalaire] منتهی می‌شود
  • در [3]، پارامترها ارائه می‌شوند
  • در [4]، نتیجه XML به‌دست آمد.

بیایید به روش getSalaireCompleted بازگردیم:


private function getSalaireCompleted(event:ResultEvent):void{
                // پیام خطا پنهان شده
                hideMsg();
                // یک فیش حقوقی دریافت می‌شود
                var feuilleSalaire:Object=event.result;
                // نمایش
                lblNom.text=feuilleSalaire.Employe.Nom;
                lblPreNom.text=feuilleSalaire.Employe.Prenom;
                lblAdresse.text=feuilleSalaire.Employe.Adresse;
                lblVille.text=feuilleSalaire.Employe.Ville;
                lblCodePostal.text=feuilleSalaire.Employe.CodePostal;
                lblIndice.text=feuilleSalaire.Employe.Indemnites.Indice;
                showEmploye();
}
  • خط ۵: feuilleSalaire=event.result نمایانگر جریان XML [4] است که توسط متد GetSalaire بازگردانده شده است. از این جریان می‌توان دید که:
    • feuilleSalaire.Employe جریان XML برای یک کارمند است
    • feuilleSalaire.Employe.Nom نام آن کارمند است
    • ...
  • خطوط ۷–۱۲: از جریان XML feuilleSalaire برای پر کردن فیلدهای مختلف کانتینر «کارمند» استفاده می‌شود.
  • خط ۱۳: کانتینر 'کارمند' نمایش داده می‌شود.

روش getSalaireFault در صورتی اجرا می‌شود که روش سرویس وب GetSalaire با خطا مواجه شود:


            private function getSalaireFault(event:FaultEvent):void{
                // نمایش پیام خطا
                msg.text=event.fault.message;
                // فرم
                showMsg();            
            }
  • خط ۳: پیام خطا event.fault.message در فیلد پیام قرار می‌گیرد
  • خط ۵: فیلد پیام نمایش داده می‌شود

این تغییرات مورد نیاز برای این نسخه جدید را به پایان می‌رساند. وقتی آن را ذخیره کنید، مشروط بر اینکه از نظر نحوی صحیح باشد، نسخه قابل اجرا در پوشه [bin-debug] پروژه ایجاد می‌شود:

 

در بالا، [main2.html] صفحه HTML است که باینری برنامه Flex، [main2.swf]، را در خود جای می‌دهد که توسط Flash Player اجرا خواهد شد.

ما می‌توانیم این نسخهٔ جدید را آزمایش کنیم:

  • سرویس وب ASP.NET باید در حال اجرا باشد
  • سرور آپاچی باید برای کلاینت فلکس در حال اجرا باشد

با فرض اینکه alias [pam-v10-flex-client-webservice] که در نسخه قبلی استفاده شده هنوز وجود دارد، ما URL و [http://localhost/pam-v10-flex-client-webservice/main2.html] را از سرور آپاچی در یک مرورگر درخواست می‌کنیم:

  • در [1]، URL درخواستی
  • به [2]، لیست کشویی کارکنان
  • در [3]، ما انتخاب را در لیست کشویی تغییر می‌دهیم تا رویداد change را فعال کنیم
  • در [4]، نتیجهٔ به‌دست‌آمده: رکورد جاستین لاورتی.

14.5. نما شمارهٔ ۳

نما شمارهٔ ۳ اعتبارسنجی فرم را انجام می‌دهد. در اینجا تنها فیلد ورودی «txtHeuresTravaillees» بررسی می‌شود. تا زمانی که فرم نادرست باشد، دکمهٔ «btnSalaire» غیرفعال باقی می‌ماند.

برای افزودن این قابلیت، [main2.mxml] را در [main3.mxml] کپی می‌کنیم:

اکنون با [main3.mxml] کار خواهیم کرد که آن را به‌عنوان برنامهٔ پیش‌فرض تنظیم می‌کنیم (به بخش 14.4 این مشخصات مراجعه کنید). ابتدا یک ویژگی به کامپوننت «txtHeuresTravaillees» اضافه می‌کنیم:


<mx:TextInput id="txtHeuresTravaillees" change="validateForm(event)"/>

هرگاه محتوای فیلد ورودی «txtHeuresTravaillees» تغییر کند، متد validateForm فراخوانی می‌شود. این یک متد محلی است که توسط توسعه‌دهنده نوشته شده است. در این متد می‌توانستیم بررسی کنیم که محتوای فیلد ورودی «txtHeuresTravaillees» واقعاً یک عدد صحیح مثبت است. در عوض، ما رویکرد متفاوتی را با استفاده از یک کامپوننت اعتبارسنجی در پیش می‌گیریم:


    <mx:NumberValidator id="heuresTravailleesValidator" source="{txtHeuresTravaillees}" property="text"
    precision="2" allowNegative="false"
    invalidCharError="Caractères invalides"
    precisionError="Deux chiffres au plus après la virgule"
    negativeError="Le nombre d'heures doit être positif ou nul"
    invalidFormatCharsError="Format invalide"
    required="true"
requiredFieldError="Donnée requise"/>
  • خط ۱: کامپوننت <mx:NumberValidator> برای بررسی اینکه آیا یک کامپوننت دیگر حاوی یک عدد صحیح یا یک عدد اعشاری است، استفاده می‌شود.
  • خط ۱: ویژگی id یک شناسه به کامپوننت اختصاص می‌دهد.
  • خط ۱: source شناسه (ID) جزئیه‌ای است که توسط جزئیه‌ی NumberValidator اعتبارسنجی می‌شود. در این مورد، فیلد ورودی «txtHeuresTravaillees» است که اعتبارسنجی می‌شود.
  • خط ۱: property نام ویژگیِ کامپوننت source است که مقدار مورد تأیید را در خود دارد. در نهایت، مقداری که تأیید می‌شود source.property است؛ در این مورد، txtHeuresTravaillees.text.
  • خط ۲: precision حداکثر تعداد رقام اعشاری مجاز را تعیین می‌کند. precision=0 بررسی می‌کند که عدد واردشده یک عدد صحیح باشد.
  • خط ۲: allowNegative نشان می‌دهد که آیا اعداد منفی مجاز هستند یا خیر
  • خط ۷: required مشخص می‌کند که آیا فیلد اجباری است یا خیر.

وقتی یک شرط اعتبارسنجی برقرار نباشد، یک پیام خطا در توپ‌تیپ کنار مؤلفه نادرست نمایش داده می‌شود. به‌طور پیش‌فرض، این پیام‌ها به زبان انگلیسی هستند. شما می‌توانید خودتان این پیام‌ها را تعریف کنید:

  • (ادامه)
    • invalidCharError: پیام خطا زمانی که متن حاوی کاراکتری باشد که نمی‌تواند در عدد ظاهر شود
    • precisionError: پیام خطا زمانی که تعداد ممیز نسبت به ویژگی precision نادرست باشد
    • negativeError: پیام خطا زمانی که عدد منفی است در حالی که ویژگی allowNegative روی "false" تنظیم شده است
    • requiredFieldError: پیام خطا زمانی که هیچ ورودی ارائه نشده در حالی که ویژگی requiredField="true" تنظیم شده است
    • invalidFormatCharsError: پیام خطا زمانی که متن حاوی کاراکترهای نامعتبر است یا در قالب نامعتبر قرار دارد؟

بیایید به کامپوننت «txtHeuresTravaillees» بازگردیم:


<mx:TextInput id="txtHeuresTravaillees" change="validateForm(event)"/>

روش validateForm می‌تواند به صورت زیر در داخل تگ <mx:Script> باشد:


        private function validateForm(event:Event):void 
        {                    
            //اعتبارسنجی ساعات کاری
            var evt:ValidationResultEvent = heuresTravailleesValidator.validate();
            // اعتبارسنجی موفق بود؟
            btnSalaire.enabled=evt.type==ValidationResultEvent.VALID;
}
  • خط ۴: اعتبارسنج «heuresTravailleesValidator» اجرا می‌شود. این اعتبارسنج نتیجه‌ای از نوع ValidationResultEvent بازمی‌گرداند.
  • خط ۶: evt.type از نوع String است و نوع رویداد را نشان می‌دهد. evt.type برای نوع ValidationResultEvent دو مقدار ممکن دارد: «نامعتبر» یا «معتبر»، که توسط ثابت‌های ValidationResultEvent.INVALID و ValidationResultEvent.VALID نشان داده می‌شوند. اگر در خط ۴ اعتبارسنجی با موفقیت انجام شده باشد، evt.type باید مقدار ValidationResultEvent.VALID را داشته باشد. در این صورت، دکمه btnSalaire فعال می‌شود؛ در غیر این صورت غیرفعال است.

این برای بررسی اعتبار ساعات کاری کافی است.

در بالا، کامپایل پروژه فایل‌های [main3.html] و [main3.swf] را تولید کرد. ما URL و [http://localhost/pam-v10-flex-client-webservice/main3.html] را در یک مرورگر بارگذاری کرده و سناریوهای خطای مختلف را بررسی می‌کنیم:

  • یک فیلد نادرست دارای حاشیه قرمز ([1, 2, 3]) است، در حالی که یک فیلد صحیح دارای حاشیه آبی ([4]) است.
  • در [4] توجه کنید که دکمه [Salaire] فعال است زیرا تعداد ساعات کاری صحیح است.

14.6. نمایش شماره ۴

نمای شماره ۴ فرم محاسبه فیش حقوقی را تکمیل می‌کند. برای این کار، ما [main3.xml] را در [main4.xml] کپی می‌کنیم و اکنون با main4 کار می‌کنیم، که آن را به عنوان برنامه پیش‌فرض تنظیم کرده‌ایم (به بخش 14.4 مراجعه کنید).

تغییرات اعمال‌شده بر روی [main4.xml] و [1] به شرح زیر است:

  • یک کانتینر عمودی جدید به نمای [2] برای نمایش اجزای حقوق کارمند اضافه شده است
  • یک کامپوننت برای قالب‌بندی مقادیر پولی به [3] اضافه شده است
  • نمایش اجزای حقوق توسط هندلری که با رویداد «کلیک» دکمه «btnSalaire» مرتبط است، انجام می‌شود.

نمایش به شرح زیر تغییر می‌کند:

کانونر جدید از همان اصل کانونر قبلی پیروی می‌کند. این یک کانونر عمودی VBox [V1] است که شامل چهار کانونر افقی HBox [Hi] می‌باشد. کانتینرهای افقی H1 تا H3 از کانتینرهای عمودی تشکیل شده‌اند که شامل دو برچسب هستند، که برچسب دوم خود در یک کانتینر عمودی قرار دارد تا رنگ پس‌زمینه را فراهم کند.


سؤال ۱: کانتینر حقوق را بنویسید. این کانتینر در ادامه با نام complements. اشاره خواهد شد.



سؤال ۲: متدهای پنهان‌سازی/نمایش کانتینر complements را بنویسید. از کاری که قبلاً برای کانتینر employe انجام شده الهام بگیرید.


ما یک هندلر به رویداد کلیک دکمه «btnSalaire» متصل می‌کنیم:


                <mx:Button id="btnSalaire" label="Salaire" click="calculerSalaire()"/>

متد calculerSalaire به شرح زیر است:


            private function calculerSalaire():void{
                // در حال آماده‌سازی فرم
                affichageSalaire=true;
                msg.text="";                
                //پارامترهای محاسبه حقوق
                heuresTravaillees=Number(txtHeuresTravaillees.text);
                joursDeTravail=int(joursTravailles.value);
                // حقوق از سرویس وب درخواست می‌شود
                pam.GetSalaire.send();
}
  • خط ۳: بولین affichageSalaire برای مشخص کردن نمایش یا عدم نمایش کانتینر complements که اجزای حقوق را نمایش می‌دهد، استفاده می‌شود. متد getSalaireCompleted در دو رویداد اجرا می‌شود:
    • وقتی کارمند در فهرست کشویی کارمندان تغییر می‌کند تا جزئیات او بدون حقوق نمایش داده شود. در این حالت، affichageSalaire را روی false تنظیم کنید.
    • محاسبه حقوق
  • خط ۶: متن در فیلد ورودی txtHeuresTravaillees به یک عدد اعشاری تبدیل می‌شود.
  • خط ۷: مقدار افزاینده joursTravailles به یک عدد صحیح تبدیل می‌شود.
  • خط ۹: متد راه دور GetSalaire فراخوانی می‌شود. شایان ذکر است که این متد سه پارامتر را انتظار دارد، از جمله پارامترهای heuresTravaillees و joursDeTravail که در خطوط 6 و 7 مقداردهی شده‌اند. همچنین باید توجه داشت که اگر فراخوانی غیرهمزمان متد GetSalaire:
    • موفق خواهد بود، متد getSalaireCompleted فراخوانی خواهد شد
    • ناموفق باشد، متد getSalaireFault فراخوانی خواهد شد

سؤال ۳: روش فعلی getSalaireCompleted را طوری گسترش دهید که اگر دکمه btnSalaire کلیک شده باشد، حقوق کارمند را نمایش دهد.


در حال حاضر اجزای حقوق بدون نماد یورو نمایش داده می‌شوند. می‌توان این نماد را در کد گنجاند یا از یک قالب‌بند استفاده کرد. این راه‌حل پیشنهادی است. قالب‌بند به شرح زیر خواهد بود:


    <mx:CurrencyFormatter id="eurosFormatter" precision="2"
        currencySymbol="" useNegativeSign="true"
alignSymbol="right"/>
  • خط ۱: id شناسه فرمت‌کننده و precision تعداد رقم اعشاری قابل نگهداری است.
  • خط ۲: currencySymbol نماد ارز مورد استفاده است. useNegativeSign مشخص می‌کند که آیا باید از علامت «-» برای مقادیر منفی استفاده شود یا خیر.
  • خط ۳: alignSymbol مشخص می‌کند که نماد ارز را نسبت به عدد در کجا قرار دهید.

این قالب‌بندی به صورت زیر در کد اسکریپت استفاده می‌شود:

                    lblSH.text=eurosFormatter.format(feuilleSalaire.Indemnites.BaseHeure);
  • eurosFormatter شناسه فرمت‌کننده مورد استفاده است
  • format متدی است که برای قالب‌بندی یک عدد فراخوانی می‌شود. این متد یک رشته را بازمی‌گرداند.
  • feuilleSalaire.Indemnites.BaseHeure عددی است که باید قالب‌بندی شود.
  • lblSH نام یک کامپوننت متن است.

سؤال ۴: متد getSalaireCompleted را طوری اصلاح کنید که از قالب‌دهندهٔ ارز استفاده کند.