آموزش Extjs 6- جلسه اول

مقدمه

در این دوره آموزشی قصد دارم با استفاده از مثال های متنوع کارکرد ها و نحوه استفاده از کتابخانه غنی Ext Js را آموزش دهم.

این دوره آموزشی شامل مباحث زیر می شود که هر کدام ممکن است 2 الی 3 جلسه به طول بینجامد و  به مرور در وبلاگ قرار خواهد گرفت:

1- شروع کار با Ext Js

2- مفاهیم پایه

3- کامپوننت های اصلی Ext Js (فرم ها و انواع فیلدهای موجود در فرم ها (شامل textfield، numberfield، chebox، radio و HtmlEditor)، اعتبار سنجی فرم ها و  هر آنچه در یک فرم مورد نیاز است.)

4- کار با داده ها

5- کار با گرید ها

6- کامپوننت های پیشرفته Extjs

7- کار با نمودارها

8- کار با تم ها و ریسپانسیو دیزاین در Ext Js

 

 

Ext Js چیست؟

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

 

چرا Ext Js؟؟ (مزایای استفاده از ext js)

پشتیبانی از انواع مرورگرها

شاید شما ساعت ها برای متناسب کردن عملکرد برنامه با مروگرهای مختلف (خصوصاً اینترنت اکسپلورر) کرده باشید. یا جایگیری عناصر را با استفاده از css بارها تغییر داده‌اید تا نتیجه در تمام مرورگرها تقریبا! یکسان شود. چرا شما به جای اینکه روی این مسائل تمرکز کنید روی منطق برنامه خود تمرکز نمی‌کنید؟ به نظر شما این اتلاف وقت نیست؟ زمانی که می‌توانستید در جهت بهبود و افزایش بهره وری برنامه بکنید باید صرف بالا و پایین کردن پیکسل‌های عناصر صفحه بکنید (که واقعاً کار طاقت‌فرسایی است!!!). اگر از یک فریم‌ورک جاوااسکریپتی حرفه ای مثل extjs استفاده کنید دیگر نیاز به فکر کردن به این مسائل را ندارید، خودش تمام کارها را انجام می دهد شما فقط روی منطق برنامه تمرکز کنید.

 

کامپوننت های قدرتمند

Ext Js با تعداد بسیار بسیار زیادی کنترل و کامپوننت آماده ارائه شده که تمام نیاز شما به هر کامپوننتی را مرتفع می کند، این کامپوننت‌ها شامل گرید، تب پنل، درخت، انتخاب‌کننده تاریخ، انواع نمودار و ... می باشد که سرعت توسعه را بسیار بالا می‌برد.

 

انقیاد دو طرفه

انقیاد دو طرفه یعنی اینکه وقتی در ظاهر برنامه مقداری تغییر کرد مدل مربوط به آن نیز به صورت اتوماتیک تغییر کند. همچنین اگر مدل شما توسط برنامه تغییر کرد در ظاهر هم آن تغییر نمایان شود.

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

 

الگوی معماری برای جاوااسکریپت

همانقدر که کدها به سمت کلاینت رفتند نگهداری از کدهای جاوااسکریپت سمت کلاینت سخت‌تر شد. با آمدن MVC یا (Model View Controller) و MVVM یا (Model View, View Model) به سمت کلاینت نگهداری از کدهای جاوااسکریپت به مراتب آسان تر شد. این الگوهای معماری در ادامه همین جلسه مورد بررسی قرار خواهد گرفت.

 

ساده سازی عملیات‌های پیچیده

میدانید ارسال یک درخواست AJAX در جاوااسکریپت به صورتی که در همه مرورگرها اجرا شود چند خط کد می شد؟  برای بررسی پیچیدگی آن می‌توانید متد AJAX از هر فریم‌ورک جاوااسکریپتی که می خواهید را بررسی کنید. یا مثلا ساخت یک گرید در جاوااسکریپت یا امکاناتی مثل صفحه بندی، مرتب سازی، فیلتر کردن، گروه بندی، فیلدهای قابل ویرایش، قابلیت کار با صفحه کلید و ... 

 

دسترسی آسان به عناصر صفحه (DOM)

در جاوااسکریپت میتوانید به عناصر صفحه یا DOM elements دسترسی داشته‌باشید ولی پیچیدگیهای خاص خودش را دارد.

 

مسیریابی سمت کلاینت (routing)

در نرم افزارهای وب routing عبارت است از اتصال url برنامه به منطق آن به صورتی که هر کس یک url را دید تشخیص دهد که قرار است چه نتیجه ای دریافت نماید. مسیریابی معمولا برای سمت سرور به کار می برد. در سمت کلاینت مسیریابی مختص SPAها (Single Page Application) هاست.

 

قابلیت دستیابی پذیری (accessibility)

قابلیت دستیابی پذیری یعنی محتوای یک برنامه باید برای افراد کم توان از نظر بصری و کسانی که با استفاده از تکنولوژی‌های کمکی (مانند انوا screen reader ها) قابل اسفاده باشد. ساخت برنامه ای با قابلیت دستیابی پذیری بالا بسیار سخت است.

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

کنسرسیوم وب جهان گستر (W3C) یک مشخصات تکنیکی تحت عنوان WAI-ARIA یا (Web Accessibility Initiative - Accessible Rich Internet Applications) ایجاد کرده است. این مشخصات راههایی که باعث می شود یک صفحه وب برای افراد ناتوان قابلیت استفاده را داشته باشد مشخص کرده است. Ext JS به صورت بسیار خوبی از این ویژگی ها و مشخصات پیروی کرده است و تمام کنترل ها و ویجت های Ext JS قابلیت دستیابی پذیری دارند و شما نیاز به هیچ کار اضافه ای ندارید.

 

معرفی اجمالی Ext JS

Ext JS یک فریم‌ورک است که به تنهایی می توانید تمام UI یک برنامه بسیار بزرگ را پیاده کنید و به هیچ چیز دیگری نیاز نداشته باشید. تمام قابلیت های ذکر شده در بالا را برای شما فراهم می آورد. مستندسازی بسیار بسیار عالی و قدرتمند با قابلیت دانلود که می‌توانید اطلاعات تمام API های فریم‌ورک را در آن مشاهده نمایید. Ext JS در ابتدا به عنوان یک کتابخانه الحاقی به YUI توسط Jack Slocum ایجاد شد و اکنون محصولی از Sencha Inc است.

در Ext JS شما تقریبا تمام کدهایتان را در جاوااسکریپت می‌نویسید و خیلی نیازی به HTML ندارید. Ext JS با تعداد بسیار زیادی کامپوننت اراپه می‌شود و زمان بسیار بسیار زیادی را برای شما صرفه‌جویی می کند.  ما در این سری آموزشی از Ext JS Version 6 استفاده می کنیم که در حال حاضر آخرین نسخه از این فریم‌ورک است. مهمترین تغییری که در Ext JS 6 رخ داده این است که دو محصول Sencha با هم ادغام شده اند: Ext JS و Sencha Touch. در ضمن Ext JS 6 با یک کامپایلر جدید SAAS با نام Fushion و بهبودهایی در نمودارهای 3D و ... آممده است.

Sencha Touch محصولی از Sencha است که برای ساخت نرم‌افزارهای تحت وب که روی دستگاه‌های موبایل و تبلت نمایش داده می‌شود استفاده می‌شد. Ext JS 4 و Ext JS 5 برای ایجاد نرم‌افزارهای تحت وب در مورورگرهای دسکتاپی استفاده می شد اما می توان برای نرم افزارهای قابل نمایش در موبایل و تپلت هم از آنها استفاده کرد با این وجود از امکانات مربوط به touch صفحه و بهره وری بهینه از شتاب دهی سخت افزاری موجود در مویابل ها بی بهره خواهید بود بنابراین بهتر بود برای نوشتن ظاهر موبايل نرم‌افزار از Sencha Touch استفاده کنید.

قبلاْ Ext JS  و Sencha Touch دو نرم افزار جداگانه بودند که کدهای هسته یکسانی داشتند ولی از جهات مختلف با هم متفاوت بودند ولی در حال حاضر این دو با هم ادغام شده اند و تحت عنوان Ext JS 6 و در قالب ۲ تول‌کیت به نام‌های classic برای مرورگرهای دسکتاپ و modern برای مرورگرهای موبایل منتشر شده که کار را برای نوشتن برنامه ای متناسب با همه مرورگرهای دسکتتاپ و موبایل و تبلت آسان منوده است. هر گاه کاربری با موبایل نرم‌افزار را مشاهده کند با ظاهری که توسط تول کیت modern ایجاد شده مواجه می شود و هرگاه با مرورگر دسکتاپی به برنامه مراجعه کند به ظاهر ایجاد شده توسط تول‌کیت classic منتقل خواهد شد. 

نکته:

toolkit ها مجموعه عناصر بصری (کنترل ها و کامپوننت ها) هستند که متناسب با مرورگر بهینه شده اند.

بنابراین در Ext JS 6 شما می توانید تعداد زیادی کد یکسان داشته و فقط گاهی باید یک سری view را به صورت مجزا برای موبایل و دسکتاپ بنویسید.

 

ادامه موضوعات درباره دانلود Ext JS 6 و ایجاد اولین نرم افزار Ext JS توسط Sencha CMD را در جلسه آینده خواهم گفت.

 

پ ن:

Sencha CMD ابزاری است که برای راحت تر کردن کار با فریم‌ورک Ext JS توسط توسعه دهندگانش ایجاد شده و بسیاری از کارهای متداول را راحت تر و سریع تر می‌کند. این نرم افزار هم در جلسه آینده بیشتر مورد بررسی قرار می‌گیرد. 

نظرات (6) -

ممنون از مطلب بسیار عالی و آموزندتون من الان این بلاگ رو پیدا کردم و حتما تا آخر اون رو دنبال می کنم

خیلی عالی بود
ممنون بابت زحماتتون و وقتی که گذاشتید

سید محمود میرخلیل سید محمود میرخلیل در 1396/8/9 16:8

طبق چیزی که در مستندات extjs من جلو رفتم شما برای استفاده از این مورد باید لایسنس 5 کاربر دوساله رو بخرین تا بتونین که توسعه بدین که تقریبا 10 میلیون تومن ایران میشه

در صورتی که پروژه شما open source باشد می‌توانید از محصولات Sencha به صورت رایگان استفاده نمایید. جهت اطلاعات بیشتر نگاهی به این لینک بیندازید:
https://www.sencha.com/legal/gpl/

البته تمام نسخه‌ها به صورت GPL ارائه نمی‌شود ولی از صفحه بالا می‌توانید آخرین نسخه GPL ارائه شده برای هر یک از محصولات رو دریافت کنید.

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

/**
* This file is part of Ext JS 4.2
*
* Copyright (c) 2011-2013 Sencha Inc
*
* Contact:  http://www.sencha.com/contact
*
* GNU General Public License Usage
* This file may be used under the terms of the GNU General Public License version 3.0 as
* published by the Free Software Foundation and appearing in the file LICENSE included in the
* packaging of this file.
*
* Please review the following information to ensure the GNU General Public License version 3.0
* requirements will be met: http://www.gnu.org/copyleft/gpl.html.
*
* If you are unsure which license is appropriate for your use, please contact the sales department
* at http://www.sencha.com/contact.
*
* Build date: 2013-03-11 22:33:40 (aed16176e68b5e8aa1433452b12805c0ad913836)
*/
/**
* List compiled by mystix on the extjs.com forums.
* Thank you Mystix!
*
* English Translations
* updated to 2.2 by Condor (8 Aug 2008)
*/
Ext.onReady(function() {
    var cm = Ext.ClassManager,
        exists = Ext.Function.bind(cm.get, cm);

    if (Ext.Updater) {
        Ext.Updater.defaults.indicatorText = '<div class="loading-indicator">درحال بارگذاری...</div>';
    }

    if (exists('Ext.data.Types')) {
        Ext.data.Types.stripRe = /[\$,%]/g;
    }

    if (Ext.Date) {
        Ext.Date.monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

        Ext.Date.getShortMonthName = function(month) {
            return Ext.Date.monthNames[month].substring(0, 3);
        };

        Ext.Date.monthNumbers = {
            Jan: 0,
            Feb: 1,
            Mar: 2,
            Apr: 3,
            May: 4,
            Jun: 5,
            Jul: 6,
            Aug: 7,
            Sep: 8,
            Oct: 9,
            Nov: 10,
            Dec: 11
        };

        Ext.Date.getMonthNumber = function(name) {
            return Ext.Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
        };

        Ext.Date.dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];

        Ext.Date.getShortDayName = function(day) {
            return Ext.Date.dayNames[day].substring(0, 3);
        };

        Ext.Date.parseCodes.S.s = "(?:st|nd|rd|th)";
    }

    if (Ext.MessageBox) {
        Ext.MessageBox.buttonText = {
            ok: "تایید",
            cancel: "لغو",
            yes: "بلی",
            no: "خیر"
        };
    }

    if (exists('Ext.util.Format')) {
        Ext.apply(Ext.util.Format, {
            currencySign: '$',
            dateFormat: 'm/d/Y'
        });
    }

    if (exists('Ext.form.field.VTypes')) {
        Ext.apply(Ext.form.field.VTypes, {
            emailText: 'این قسمت باید یک آدرس ایمیل باشد مثال:"[email protected]"',
            urlText: 'این قسمت بایستی آدرسی روی اینترنت باشد مثال : "http:/' + '/www.example.com"';,
            alphaText: 'این فیلد می تواند فقط شامل حروف و _ باشد',
            alphanumText: 'این فیلد می تواند فقط شامل حروف و اعداد و _ باشد'
        });
    }
});


Ext.define("Ext.locale.fa.view.View", {
    override: "Ext.view.View",
    emptyText: "",
  launch: function() {
        Ext.create('Ext.container.Viewport', {
            layout: 'fit',
            items: [
                {
                    title: 'Hello Ext',
                    html : 'Hello! Welcome to Ext JS.'
                }
            ]
        });
    }
});

Ext.define("Ext.locale.fa.grid.plugin.DragDrop", {
    override: "Ext.grid.plugin.DragDrop",
    dragText: "{0} selected row{1}"
});

// changing the msg text below will affect the LoadMask
Ext.define("Ext.locale.fa.view.AbstractView", {
    override: "Ext.view.AbstractView",
    msg: "...درحال بارگذاری"
});

Ext.define("Ext.locale.fa.picker.Date", {
    override: "Ext.picker.Date",
    todayText: "امروز",
    minText: "این تاریخ از حداقل کمتر است",
    maxText: "این تاریخ از حداکثر بیشتر است",
    disabledDaysText: "",
    disabledDatesText: "",
    monthNames: Ext.Date.monthNames,
    dayNames: Ext.Date.dayNames,
    nextText: 'Next Month (Control+Right)',
    prevText: 'Previous Month (Control+Left)',
    monthYearText: 'Choose a month (Control+Up/Down to move years)',
    todayTip: "{0} (Spacebar)",
    format: "m/d/y",
    startDay: 0
});

Ext.define("Ext.locale.fa.picker.Month", {
    override: "Ext.picker.Month",
    okText: "&#160;OK&#160;",
    cancelText: "لغو"
});

Ext.define("Ext.locale.fa.toolbar.Paging", {
    override: "Ext.PagingToolbar",
    beforePageText: "صفحه",
    afterPageText: "از {0}",
    firstText: "اولین صفحه",
    prevText: "صفحه قبل",
    nextText: "صفحه بعد",
    lastText: "آخرین صفحه",
    refreshText: "تازه سازی",
    displayMsg: "نمایش {0} - {1} از {2}",
    emptyMsg: 'اطلاعاتی برای نمایش وجود ندارد'
});

Ext.define("Ext.locale.fa.form.Basic", {
    override: "Ext.form.Basic",
    waitTitle: "لطفا منتظر بمانید..."
});

Ext.define("Ext.locale.fa.form.field.Base", {
    override: "Ext.form.field.Base",
    invalidText: "مقدار وارد شده در این فیلد نامعتبر است"
});

Ext.define("Ext.locale.fa.form.field.Text", {
    override: "Ext.form.field.Text",
    minLengthText: "حداقل طول کارکتر مجاز در این فیلد {0} است",
    maxLengthText: "حداکثر طول کارکتر مجاز در این فیلد {0} است",
    blankText: "این فیلد اجباری است",
    regexText: "",
    emptyText: null
});

Ext.define("Ext.locale.fa.form.field.Number", {
    override: "Ext.form.field.Number",
    minText: "حداقل تعداد کارکتر مجاز برای این فیلد {0} است",
    maxText: "حداکثر تعداد کارکتر مجاز برای این فیلد {0} است",
    nanText: "{0} مقدار وارد شده معتبر نیست"
});

Ext.define("Ext.locale.fa.form.field.Date", {
    override: "Ext.form.field.Date",
    disabledDaysText: "غیرفعال",
    disabledDatesText: "غیرفعال",
    minText: "The date in this field must be after {0}",
    maxText: "The date in this field must be before {0}",
    invalidText: "{0} is not a valid date - it must be in the format {1}",
    format: "m/d/y",
    altFormats: "m/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d"
});

Ext.define("Ext.locale.fa.form.field.ComboBox", {
    override: "Ext.form.field.ComboBox",
    valueNotFoundText: undefined
}, function() {
    Ext.apply(Ext.form.field.ComboBox.prototype.defaultListConfig, {
        loadingText: "در حال بارگذاری..."
    });
});

Ext.define("Ext.locale.fa.form.field.HtmlEditor", {
    override: "Ext.form.field.HtmlEditor",
    createLinkText: 'لطفا آدرس را برای این لینک وارد کنید:'
}, function() {
    Ext.apply(Ext.form.field.HtmlEditor.prototype, {
        buttonTips: {
            bold: {
                title: 'Bold (Ctrl+B)',
                text: 'Make the selected text bold.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            italic: {
                title: 'Italic (Ctrl+I)',
                text: 'Make the selected text italic.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            underline: {
                title: 'Underline (Ctrl+U)',
                text: 'Underline the selected text.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            increasefontsize: {
                title: 'Grow Text',
                text: 'Increase the font size.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            decreasefontsize: {
                title: 'Shrink Text',
                text: 'Decrease the font size.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            backcolor: {
                title: 'Text Highlight Color',
                text: 'Change the background color of the selected text.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            forecolor: {
                title: 'Font Color',
                text: 'Change the color of the selected text.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            justifyleft: {
                title: 'Align Text Left',
                text: 'Align text to the left.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            justifycenter: {
                title: 'Center Text',
                text: 'Center text in the editor.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            justifyright: {
                title: 'Align Text Right',
                text: 'Align text to the right.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            insertunorderedlist: {
                title: 'Bullet List',
                text: 'Start a bulleted list.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            insertorderedlist: {
                title: 'Numbered List',
                text: 'Start a numbered list.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            createlink: {
                title: 'Hyperlink',
                text: 'Make the selected text a hyperlink.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            sourceedit: {
                title: 'Source Edit',
                text: 'Switch to source editing mode.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            }
        }
    });
});

Ext.define("Ext.locale.fa.grid.header.Container", {
    override: "Ext.grid.header.Container",
    sortAscText: "مرتب سازی صعودی",
    sortDescText: "مرتب سازی نزولی",
    columnsText: "ستون"
});

Ext.define("Ext.locale.fa.grid.GroupingFeature", {
    override: "Ext.grid.GroupingFeature",
    emptyGroupText: '(خالی)',
    groupByText: 'گروه با این فیلد',
    showGroupsText: 'نمایش گروه ها'
});

Ext.define("Ext.locale.fa.grid.PropertyColumnModel", {
    override: "Ext.grid.PropertyColumnModel",
    nameText: "نام",
    valueText: "مقدار",
    dateFormat: "m/j/Y",
    trueText: "دارد",
    falseText: "ندارد"
});

Ext.define("Ext.locale.fa.grid.BooleanColumn", {
    override: "Ext.grid.BooleanColumn",
    trueText: "دارد",
    falseText: "ندارد",
    undefinedText: '&#160;'
});

Ext.define("Ext.locale.fa.grid.NumberColumn", {
    override: "Ext.grid.NumberColumn",
    format: '0,000.00'
});

Ext.define("Ext.locale.fa.grid.DateColumn", {
    override: "Ext.grid.DateColumn",
    format: 'm/d/Y'
});

Ext.define("Ext.locale.fa.form.field.Time", {
    override: "Ext.form.field.Time",
    minText: "The time in this field must be equal to or after {0}",
    maxText: "The time in this field must be equal to or before {0}",
    invalidText: "{0} is not a valid time",
    format: "g:i A",
    altFormats: "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H"
});

Ext.define("Ext.locale.fa.form.CheckboxGroup", {
    override: "Ext.form.CheckboxGroup",
    blankText: "You must select at least one item in this group"
});

Ext.define("Ext.locale.fa.form.RadioGroup", {
    override: "Ext.form.RadioGroup",
    blankText: "بایستی انتخاب کنید یکی از موارد این گروه را"
});

// This is needed until we can refactor all of the locales into individual files
Ext.define("Ext.locale.fa.Component", {
    override: "Ext.Component"
});

ارسال نظر