یک captcha حرفهای
اگرچه شیئ Date در جاوااسکریپت ویژگیهای متنوعی برای کارکردن با تاریخ و زمان در اختیار برنامهنویسان قرار میدهد، ولی توسعهی نرمافزارهای تحت وب تنها با استفاده از این ویژگیها گاهی مشکل و ناهموار به نظر میرسد.
<link href="_content/Bit.Client.Web.BlazorUI/styles/bit.blazorui.min.css" rel="stylesheet" />
<script src="_content/Bit.Client.Web.BlazorUI/scripts/bit.blazorui.min.js"></script>
@using Bit.Client.Web.BlazorUI
<BitButton>Hello!</BitButton>
<BitDatePicker SelectedDate="@BirthDate"></BitDatePicker>
CultureInfo.CurrentUICulture = new CultureInfo("fa-IR");
<BitDatePicker Culture="@(new System.Globalization.CultureInfo("en-US"))" />
var cultureInfo = CultureInfo.CreateSpecificCulture("fa-IR")
cultureInfo.DateTimeFormat.MonthNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
در مطلب جاری، روش فراخوانی توابع جاوااسکریپتی را از طریق کدهای #C برنامههای Blazor بررسی کردیم؛ عکس آن نیز میسر است و یکی از کاربردهای آن، ارسال نتایج کتابخانههای جاوااسکریپتی، به کدهای یک کامپوننت است. برای مثال کاربری در یک کامپوننت تقویم باز شده، روزی را انتخاب میکند. میخواهیم نتیجهی این انتخاب او را که در سمت کدهای جاوااسکریپتی رخداده، به نحوی به کدهای #C یک کامپوننت منتقل کنیم و یا حتی محاسباتی را در سمت کدهای #C انجام دهیم و به کدهای جاوااسکریپتی منتقل کنیم.
الف) فراخوانی متدهای استاتیک #C از طریق کدهای جاوااسکریپتی
فرض کنید متد استاتیک HelpMessage را میخواهیم از طریق کدهای جاوااسکریپتی فراخوانی کنیم. برای این منظور، یک چنین تابعی باید به ویژگی JSInvokable مزین شود:
@page "/js-sample" <button class="btn btn-primary" onclick="JsFunctionHelper.invokeDotnetStaticFunction()">Invoke Static Method</button> @code { [JSInvokable] public static Task<string> HelpMessage() { return Task.FromResult("Help text from C# static function"); } }
سپس در سمت در فایل Client\wwwroot\main.js برای فراخوانی متد HelpMessage خواهیم داشت:
window.JsFunctionHelper = { invokeDotnetStaticFunction: function () { DotNet.invokeMethodAsync("BlazorRazorSample.Client", "HelpMessage").then( (data) => { console.log(data); } ); } };
ب) فراخوانی متدهای غیر استاتیک #C از طریق کدهای جاوااسکریپتی
فراخوانی instance methodهای کامپوننتها از طریق کدهای #C، کمی پیچیدهتر است:
@page "/js-sample" @implements IDisposable @inject IJSRuntime jSRuntime <button class="btn btn-primary" @onclick="CallInstanceMethod">Invoke Instance Method</button> @code { private DotNetObjectReference<JsSample> objectReference; [JSInvokable] public string GetAddress() { return "123 Main Street"; } protected override async Task OnAfterRenderAsync(bool firstRender) { if(firstRender) { objectReference = DotNetObjectReference.Create(this); } } private async Task CallInstanceMethod() { await jSRuntime.InvokeVoidAsync("JsFunctionHelper.invokeDotnetInstanceFunction", objectReference); } public void Dispose() { objectReference?.Dispose(); } }
- همچنین در اینجا onclick تعریف شده، به متدی داخل همین کامپوننت اشاره میکند.
- این ارجاع نیز باید در پایان کار کامپوننت، Dispose شود. به همین جهت implements IDisposable@ را مشاهده میکنید.
اکنون کدهای جاوا اسکریپتی که از این وهلهی دریافتی استفاده میکند، به صورت زیر خواهد بود. در این کدها addressProvider همان objectReference دریافتی است که توسط آن میتوان متد غیراستاتیک GetAddress کامپوننت را فراخوانی کرد:
window.JsFunctionHelper = { invokeDotnetInstanceFunction: function (addressProvider) { addressProvider.invokeMethodAsync("GetAddress").then((data) => { console.log(data); }); } };
در قسمت قبل بیان شد همراه با نصب Angular Material، تعدادی تم از قبل ساخته شده نیز نصب خواهند شد که شامل یکسری استایل با رنگهای مشخصی هستند. این تمها عبارتند از:
- indigo-pink
- deeppurple-amber
- purple-green
- pink-bluegrey
انگیولار متریال ۲ علاوه بر این، امکاناتی برای ایجاد تم سفارشی را نیز فراهم کرده است. در این بخش قصد داریم برای قالب نمونهای که قبلا ایجاد کرده بودیم یک تم سفارشی بسازیم.
مقدمه
تم در انگیولار متریال، از ترکیب چند پالت رنگی، ساخته میشود. پالتهای رنگ را در طراحی متریال ( Material Design ) در اینجا میتوانید مشاهده کنید. انگیولار متریال رنگهای مورد استفاده خود را در گروههای زیر دسته بندی کرده است.
- Primary : این پالت رنگی به صورت گسترده در
بخشهای مختلف صفحه و کامپوننتها مورد استفاده قرار میگیرد.
- Accent : این پالت رنگی برای دکمههای
شناور و همچنین المنتهای تعاملی مورد استفاده قرار میگیرد.
- Warn : این پالت رنگی برای مشخص کردن
حالتهای خطا، مورد استفاده قرار میگیرد.
- Foreground : این پالت رنگی برای متون و
آیکونها مورد استفاده قرار میگیرد.
- Background : این پالت رنگی برای المنتهای پس
زمینه مورد استفاده قرار میگیرد.
در انگیولار متریال تمامی تمها
در زمان build به صورت استاتیک تولید میشوند. این قابلیت با خارج کردن چرخه
تولید تم از چرخه راهاندازی برنامه، باعث بهبود در راهاندازی خواهد شد.
تعریف تم سفارشی
برای ساخت تم سفارشی نیاز به یک فایل Sass خواهیم داشت. پس در مسیر /src یک فایل Sass را با نام my-custom-theme.scss ایجاد میکنیم (شما میتوانید از هر نام دیگری برای فایل Sass استفاده کنید). اگر از AngularCLI برای برنامههای خود استفاده میکنید، بایستی فایل Sass ایجاد شده را به لیست استایلها در فایل angular-cli.json اضافه کنید. این کار باعث میشود AngularCLI این فایل Sass را در زمان build به css کامپایل کند.
نکته: استفاده از فایل Sass برای ساختن تم سفارشی به این معنی نیست که شما از Sass برای سایر Style های برنامه خود استفاده کنید.
"styles": [ "styles.css", "my-custom-theme.scss" ],
اگر از AngularCLI استفاده نمیکنید، شما نیاز به ابزاری برای کامپایل فایل Sass به css خواهید داشت. ابزارهای بسیاری در این زمینه وجود دارند از جمله: gulp-sass و grunt-sass . ولی سادهترین ابزار برای این کار node-sass میباشد. کافی است بعد از نصب، دستور زیر را اجرا کنید تا فایل sass به css کامپایل شود. فایل css تولید شده را مستقیما در صفحه index.html خود میتوانید استفاده کنید.
node-sass src/my-custom-theme.scss dist/my-custom-theme.css
در فایل تم ایجاد شده ( my-custom-theme.scss ) ابتدا بایستی فایل Sass اصلی انگیولار متریال را وارد کنید.
@import '~@angular/material/theming';
در قدم بعدی mixin تعریف شده با نام mat-core را در فایل Sass انگیولار متریال، وارد میکنیم. این mixin شامل تمامی Styleهای مشترکی است که توسط کامپوننتهای مختلف استفاده میشود.
@include mat-core();
نکته: مطمئن شوید فقط یک بار این mixin را در سرتاسر برنامه خود وارد کرده باشید. در غیر این صورت، فایل css تولید شده شامل یکسری Style تکراری خواهد بود و این باعث بزرگ و حجیم شدن فایل css نهایی خواهد شد.
تا اینجا فایل تم ایجاد شده اینگونه خواهد بود:
@import '~@angular/material/theming'; @include mat-core();
حالا نوبت تعریف تم سفارشی است. ولی قبل از آن باید با سیستم رنگها در طراحی
متریال ( Material
Design ) آشنایی داشته
باشیم. در طراحی متریال ۱۹ پالت رنگی با نامهای مختلف وجود دارند. برای ۱۶ پالت رنگی، ۱۴ طیف رنگی و برای ۳ پالت رنگی دیگر، ۱۰ طیف رنگی در نظر گرفته شده است. هر کدام از این طیفهای رنگی، دارای یک مقدار عددی است. یعنی یک رنگ در سیستم طراحی متریال متشکل از یک نام رنگ و یک شماره طیف رنگ است که مقدار پیش فرض طیف رنگ، عدد ۵۰۰ میباشد.
حالا با استفاده از تابع mat-palette تعریف شده در فایل Sass انگیولار متریال، سه متغیر را برای رنگهای Primary ، Accent و Warn در فایل my-custom-theme.scss ، به شکل زیر تعریف میکنیم.
$my-app-primary: mat-palette($mat-indigo); $my-app-accent: mat-palette($mat-pink, 500, A100, A400); $my-app-warn: mat-palette($mat-deep-orange);
تابع mat-palette در فایل Sass اصلی انگیولار متریال، به شکل زیر تعریف شده است.
@function mat-palette($base-palette, $default: 500, $lighter: 100, $darker: 700)
این
تابع یک پارامتر اجباری دارد و بقیه پارامترها اختیاری هستند.
- base-palette $: نام رنگ را دریافت میکند. این پارامتر
اجباری است و باید مشخص شود.
- default$: با این
پارامتر، طیف پیشفرض رنگ انتخاب شده را مشخص میکنیم. این پارامتر اختیاری است و
مقدار پیش فرض آن 500 است.
- lighter$: با این پارامتر، طیف روشن رنگ انتخاب شده را مشخص میکنیم. این
پارامتر اختیاری است و مقدار پیش فرض آن 100 است.
- darker$: با این پارامتر، طیف تیره رنگ انتخاب شده را مشخص میکنیم. این
پارامتر اختیاری است و مقدار پیش فرض آن 700 است.
در قدم آخر با استفاده از تابع mat-light-theme یا mat-dark-theme، رنگهای تعریف شده در مرحله قبل را ترکیب کرده و نتیجه را به عنوان ورودی به mixin به نام angular-material-theme ارسال و بارگذاری میکنیم.
تابع mat-light-theme و mat-dark-theme سه پارامتر را دریافت میکند. پارارمتر اول پالت رنگ ایجاد شده توسط تابع mat-palette برای گروه Primary ، پارامتر دوم پالت رنگ ایجاد شده برای گروه Accent و پارامتر سوم پالت رنگ ایجاد شده برای گروه Warn را دریافت میکند. دو پارامتر اول اجباری و پارامتر سوم اختیاری با مقدار پیش فرض mat-palette($mat-red) میباشد.
شکل
کلی فایل Sass در نهایت به شکل زیر خواهد
بود.
@import '~@angular/material/theming'; @include mat-core(); $my-app-primary: mat-palette($mat-teal); $my-app-accent: mat-palette($mat-amber, 500, A100, A400); $my-app-warn: mat-palette($mat-deep-orange); $my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn); @include angular-material-theme($my-app-theme);
برای استفاده از پالت رنگهای ایجاد شده، از خصوصیت color در المنتهای انگولار متریال استفاده میکنیم. برای نمونه بعد از تغییر فایل Sass به شکل بالا و حذف لینک تم از پیش ساخته شده که در پست قبلی به Style.cs اضافه کرده بودیم، میتوانیم کار خود را به صورت زیر آزمایش کنیم. در فایل app.component.html در تگ main کدهای زیر را اضافه کنید.
<md-card> <button md-raised-button color="primary"> Primary </button> <button md-raised-button color="accent"> Accent </button> <button md-raised-button color="warn"> Warning </button> </md-card>
خروجی زیر را مشاهده خواهید کرد.
همچنین میتوانید به جای استفاده از تابع mat-light-theme از تابع mat-dark-theme استفاده کنید. دراین صورت خروجی زیر را خواهید دید.
در بخش بعدی نحوه ساخت چند تم دیگر را در کنار تم اصلی، ساخت تم به ازای هر کامپوننت و نحوه تعویض تم از طریق کد را دنبال خواهیم کرد.
کدهای این قسمت را از اینجا دریافت کنید: ساخت-تم-سفارشی-در-انگولار-متریال-۲---بخش-اول.rar