- از NET Core CLI. استفاده میکنید (از روش ... dotnet ef)؟ از پارامتر v- آن استفاده کنید (verbose-)
- سازندهی کلاس Context شما وابستگی خاصی دارد؟ آیا IDesignTimeDbContextFactory را برای آن مشخص کردهاید؟
بنابراین برای ایجاد یک کامپوننت میتوانیم به اینصورت عمل کنیم:
var app = angular.module("dntModule", []); app.component("pmApp", { template: `Hello this is a simple component` });
همانطور که مشاهده میکنید تابع component دو پارامتر را از ورودی دریافت خواهد کرد؛ نام کامپوننت و یک شیء برای تعیین تنظیمات کامپوننت. نام کامپوننت در اینجا به صورت camel case تعریف شده است؛ که در واقع یک convention برای Angular است. در اینحالت برای استفادهی از کامپوننت باید به اینصورت عمل کنیم:
<pm-app></pm-app>
در قسمت تنظیمات کامپوننت، در سادهترین حالت یک template تعیین شدهاست که بیانگر نحوهی رندر شدن یک کامپوننت میباشد. در اینحالت وقتی انگیولار به تگ فوق برسد، یک کامپوننت با نام pmApp را بارگذاری خواهد کرد.
ایجاد یک کامپوننت ساده
در ادامه میخواهیم یک کامپوننت ساده را جهت نمایش یکسری URL درون صفحه طراحی کنیم. ساختار صفحه index.html به صورت زیر خواهد بود:
<html ng-app="DNT"> <head> <meta charset="UTF-8"> <title>Using Angular Component</title> <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css"> <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css"> </head> <body> <div class="container"> <div class="row"> <div class="col-md-3"> <dnt-widget></dnt-widget> </div> </div> </div> <script src="bower_components/angular/angular.js"></script> <script src="scripts/app.js"></script> <script src="scripts/components/dnt-widget.component.js"></script> </body> </html>
در اینجا ابتدا توسط دایرکتیو ng-app، به Angular، ماژولمان را معرفی کردهایم. سپس مداخل بوتاسترپ و کتابخانهی font-awesome را مشاهده میکنید. در ادامه، کتابخانهی Angular و همچنین فایل app.js جهت معرفی ماژول برنامه معرفی شدهاست. در نهایت نیز یک فایل در مسیر ذکر شده برای قرار دادن کدهای کامپوننت در مسیر scripts/components اضافه شدهاست.
همانطور که ملاحظه میکنید، کامپوننتمان به صورت یک تگ سفارشی، درون صفحه قرار گرفته است:
<dnt-archive></dnt-archive>
در ادامه باید به Angular، نحوهی تعریف این کامپوننت را اعلام کنیم. بنابراین یک فایل جاوا اسکریپتی را با نام dnt-widget.component، با محتویات زیر ایجاد کنید:
(function () { "use strict"; var app = angular.module("DNT"); function DntArchiveController() { var model = this; model.panel = { title: "Panel Title", items: [ { title: "Dotnettips", url: "https://www.dntips.ir" }, { title: "Google", url: "http://www.google.con" }, { title: "Yahoo", url: "http://www.yahoo.con" } ] }; }; app.component("dntWidget", { templateUrl: '/scripts/components/dnt-widget.component.html', controllerAs: "model", controller: DntArchiveController }); } ());
توضیح کدهای فوق:
همانطور که مشاهده میکنید، برای پارمتر دوم کامپوننت، سه پراپرتی را تعیین کردهایم:
templateUrl: به کمک این پراپرتی به Angular گفتهایم که محتوای قالب این کامپوننت، درون یک فایل HTML مجزا قرار دارد و به صورت linked template میباشد.
controllerAs: یکی از مزایای استفاده از کامپوننتها، استفاده از controller as syntax میباشد. لازم به ذکر است اگر این پراپرتی را مقداردهی نکنیم، به صورت پیشفرض مقدار ctrl$ در نظر گرفته خواهد شد.
controller: مزیت دیگر کامپوننتها، استفاده از کنترلرها است. با استفاده از این پراپرتی، یک کنترلر را برای کامپوننتمان رجیستر کردهایم. در نتیجه زمانیکهی Angular میخواهد کامپوننتمان را نمایش دهد، تابع تعریف شده برای این پراپرتی، جهت ایجاد یک controller instance فراخوانی خواهد شد. بنابراین هر پراپرتی یا تابعی که برای این controller instance تعریف کنیم، به راحتی درون ویوی آن جهت اعمال بایندینگ در دسترس خواهد بود (در نتیجه نیازی به scope$ نخواهد بود).
درون کنترلر نیز برای راحتی کار و همچنین به عنوان یک best practice، مقدار this را توسط یک متغیر با نام model، کپچر کردهایم. در اینجا یک شیء را با نام panel نیز به مدل اضافه کردهایم.
محتویات تمپلیت:
<div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title"> <span class="fa fa-archive"></span> {{ model.panel.title}} </h3> </div> <ul class="list-group"> <li class="list-group-item" ng-repeat="item in model.panel.items"> <span class="fa fa-industry"></span> <a href="{{ item.url }}">{{ item.title }}</a> </li> </ul> </div>
ویوی کامپوننت پیچیدگی خاصی ندارد. همانطور که مشاهده میکنید یک پنل بوتاسترپی را ایجاد کردهایم که مقدار عنوان آن و همچنین آیتمهای آن، از شیء اتچ شده به مدل دریافت خواهند شد. بنابراین اکنون اگر برنامه را اجرا کنید، خروجی کامپوننت را به اینصورت مشاهده خواهید کرد:
همانطور که مشاهده میکنید استفاده از کامپوننتها در Angular 1.5 در مقایسه با ایجاد دایرکتیوها و کنترلرها خیلی سادهتر است. در واقع امکانات این API جدید تنها به مثال فوق ختم نمیشود؛ بلکه این API یک سیستم مسیریابی جدید را نیز معرفی کرده است که در قسمتهای بعدی به آن نیز خواهیم پرداخت.
جهت تکمیل بحث نیز یک تقویم شمسی ساده را در اینجا قرار دادهام. میتوانید جهت مرور بحث جاری به کدهای آن مراجعه کنید. البته هدف از تعریف این پروژه تنها یک مثال ساده برای معرفی کامپوننتها بود و طبیعتاً باگهای زیادی دارد. اگر مایل بودید میتوانید در توسعهی آن مشارکت نمائید.
کدهای این قسمت را نیز از اینجا میتوانید دریافت کنید.
در قسمت قبلی درباره ایجاد نمودار سازمانی تحت وب صحبت کردیم .حال اگر بخواهیم آن را با رنگهای مختلف ایجاد کنیم مانند شکل ذیل :
بدین صورت باید عمل کنیم:
نمودار در داخل canvas رسم شده است. برای اینکه پس زمینه (background) و حاشیههای آن (borders) را رنگ آمیزی کنیم، باید تابع رنگ آمیزی را قبل از تابع رسم نمودار صدا بزنیم. میتوانید از کدهای ذیل استفاده نمائید:
// ایجاد یک پس زمینه رنگی: var c = document.getElementById("c_canvas"); var cxt = c.getContext("2d"); var gradient = cxt.createLinearGradient(0, 0, 800, 320) gradient.addColorStop(0, 'Red'); gradient.addColorStop(.5, 'Yellow'); gradient.addColorStop(1, 'Green'); cxt.fillStyle = gradient; cxt.fillRect(0, 0, 800, 320); cxt.save(); // این سه خط را فعال کرده تا انتقال نمودار چارت سازمانی را مشاهده نمائید. //cxt.scale(-1.1, 1.1); //cxt.translate(-700,-50); //cxt.rotate(0.2); var o = new orgChart(); o.addNode(1, '', '', 'Root node'); o.addNode(2, 1, 'u', 'u-node 1'); o.addNode(3, 1, 'u', 'u-node 2'); o.addNode(4, 1, 'u', 'u-node 3'); o.addNode(5, 1, 'l', 'l-node 1'); o.addNode(6, 1, 'l', 'l-node 2'); o.addNode(7, 1, 'r', 'r-node 1'); o.addNode(8, 1, 'r', 'r-node 2'); o.addNode(9, 1, 'r', 'r-node 3'); o.addNode('', '', '', 'Root 2'); o.addNode('', 'Root 2', 'r', 'using'); o.addNode('', 'Root 2', 'r', 'text as id'); o.drawChart('c_canvas', 'center'); cxt.restore();
نکته : اگر بخواهید رنگ پس زمینه canvas را کامل پر کند (Fill) باید رسم نمودار را دوبار انجام دهید، در ابتدا تعریف یک canvas با امکان پرشونده در صفحه ، و بعد رسم پس زمینه و بعد رسم دوباره canvas .
شاخهها میتوانند رنگهای متفاوتی داشته باشند. امکان تعریف رنگ شاخهها بهمراه صدا زدن تابع addNode وجود دارد. اگر رنگی تعریف نشود ، از رنگ پیشفرض استفاده خواهد شد. رنگهای کنونی را با صدا زدن تابع setColor میتوان عوض کرد و تا زمان صدا زدن تابع setColor بعدی از آنها استفاده خواهد شد. همه خطهایی که شاخهها را به هم متصل میکنند فقط یک رنگ مشابه میتوانند داشته باشند.
پارامترهای تابع setColor :
یک پارامتر خالی رنگ ، تنظیمات کنونی را تغییر نخواهد داد. کد زیر را ویرایش نموده و دوباره صفحه خود را بازخوانی نمائید.
var o = new orgChart(); o.setColor('#99CC99', '#CCFFCC', '#000000', '#FF0000'); o.addNode(0, '', '', 'Root node'); o.setColor('#CCCC66', '#FFFF99'); o.addNode(11, 0, 'u', 'u-node 1'); o.setColor('#000000', '#FFFF99'); o.addNode(12, 0, 'u', 'black border'); o.addNode(13, 0, 'u', 'bold black border', 1); o.setColor('#CC4950', '#FF7C80'); o.addNode(21, 0, 'l', 'l-node 1'); o.addNode(22, 0, 'l', 'l-node 2', 0, 'BLACK', 'RED', 'BLUE'); o.addNode(23, 0, 'l', 'l-node 3'); o.setColor('#CC9966', '#FFCC99'); o.addNode(31, 0, 'r', 'r-node 1'); o.drawChart('c_colors', 'center');
<body> <div class="container"> <h2>Medical Questionnaire</h2> <form> <fieldset> <legend>Owner Info</legend> <div> <label for="ownername">Owner name</label> <input type="text" id="ownername" placeholder="Your Name"> </div> <div> <label for="owneremail">Email address</label> <input type="email" id="owneremail" aria-describedby="emailHelp" placeholder="Enter email"> <small id="emailHelp">We'll never share your email</small> </div> </fieldset> <fieldset> <legend>Pet Info</legend> <div> <label for="petname">Pet name</label> <input type="text" id="petname" placeholder="Your Pet's name"> </div> <div> <label for="pettype">Pet type</label> <select id="pettype"> <option>Choose</option> <option value="cat">Dog</option> <option value="cat">Cat</option> <option value="bird">Other</option> </select> </div> <div> <label for="reasonforvisit">Reason for today's visit</label> <textarea id="reasonforvisit" rows="3"></textarea> </div> <div> <label>Has your pet been spayed or neutered?</label> <label><input type="radio" name="spayneut" value="yes" checked> Yes</label> <label><input type="radio" name="spayneut" value="no"> No</label> </div> <div> <label>Has the pet had any of the following in the past 30 days</label> <label><input type="checkbox"> Abdominal pain</label> <label><input type="checkbox"> Lack of appetite</label> <label><input type="checkbox"> Weakness</label> </div> </fieldset> <button type="submit">Submit</button> </form> </div><!-- content container --> </body>
<div class="form-check"> <label class="form-check-label"> <input class="form-check-input" type="checkbox"> Lack of appetite </label> </div>
<div class="form-group"> <label class="d-block">Has your pet been spayed or neutered?</label> <div class="form-check form-check-inline"> <label class="form-check-label"> <input class="form-check-input" type="radio" name="spayneut" value="yes" checked> Yes </label> </div> <div class="form-check form-check-inline"> <label class="form-check-label"> <input class="form-check-input" type="radio" name="spayneut" value="no"> No </label> </div> </div>
<div class="form-group"> <label for="owneremail" class="text-success">Email address</label> <input class="form-control is-valid" type="email" id="owneremail" aria-describedby="emailHelp" placeholder="Enter email"> <small class="form-text text-muted" id="emailHelp">We'll never share your email</small> <div class="valid-feedback"> Looks good! </div> </div>
<body> <div class="container"> <h2>Medical Questionnaire</h2> <form> <fieldset class="form-group"> <legend>Owner Info</legend> <div class="form-group row"> <label class="form-control-label col-md-2 col-form-label text-md-right" for="ownername">Owner</label> <div class="col-md-10"> <input class="form-control" type="text" id="ownername" placeholder="Your Name"> </div> </div> <div class="form-group row"> <label class="form-control-label col-md-2 col-form-label text-md-right" for="owneremail">Address</label> <div class="col-md-10"> <input class="form-control" type="text" id="owneremail" placeholder="Address"> </div> </div> <div class="form-group row"> <div class="form-group col-6 offset-md-2"> <label class="form-control-label sr-only" for="ownercity">City</label> <input class="form-control" type="text" id="ownercity" placeholder="City"> </div> <div class="form-group col-md-4 col-6"> <label class="form-control-label sr-only" for="ownerzip">Zip</label> <input class="form-control" type="text" id="ownerzip" placeholder="Zip"> </div> </div> <div class="form-group row"> <div class="offset-md-2 col-md-10"> <button class="btn btn-primary" type="submit">Submit</button> </div> </div> </fieldset> </form> </div> </body>
<div class="form-group row"> <label class="form-control-label col-md-2 col-form-label text-md-right" for="ownername">Owner</label> <div class="col-md-10"> <input class="form-control" type="text" id="ownername" placeholder="Your Name"> </div> </div>
<div class="form-group row"> <div class="form-group col-6 offset-md-2"> <label class="form-control-label sr-only" for="ownercity">City</label> <input class="form-control" type="text" id="ownercity"placeholder="City"> </div>
<div class="form-group row"> <div class="offset-md-2 col-md-10"> <button class="btn btn-primary" type="submit">Submit</button> </div> </div>
<div class="form-group"> <label class="form-control-label" for="donationamt"> Donation Amount </label> <div class="input-group"> <div class="input-group-prepend"> <span class="input-group-text">$</span> </div> <input type="text" class="form-control" id="donationamt" placeholder="Amount"> <div class="input-group-append"> <span class="input-group-text">.00</span> </div> </div> </div>
<nav class="navbar bg-dark navbar-dark navbar-expand-sm"> <div class="container"> <div class="navbar-brand d-none d-sm-inline-block"> Wisdom Pet Medicine </div> <div class="navbar-nav mr-auto"> <a class="nav-item nav-link active" href="#">Home</a> <a class="nav-item nav-link" href="#">Mission</a> <a class="nav-item nav-link" href="#">Services</a> <a class="nav-item nav-link" href="#">Staff</a> <a class="nav-item nav-link" href="#">Testimonials</a> </div> <form class="form-inline d-none d-md-inline-block"> <div class="input-group"> <label for="search" class="form-control-label sr-only"></label> <input type="text" id="search" class="form-control" placeholder="Search ..."> <div class="input-group-append"> <button class="btn btn-outline-light" type="submit">Go</button> </div> </div> </form> </div> </nav>
https://www.dntips.ir/(xxxxxx)/page.aspx
Response.ApplyAppPathModifier
Set-Cookie: <name>=<value>[; <Max-Age>=<age>] [; expires=<date>][; domain=<domain_name>] [; path=<some_path>][; secure][; HttpOnly]
<httpCookies httpOnlyCookies="true" …>
HttpCookie myCookie = new HttpCookie("myCookie"); myCookie.HttpOnly = true; Response.AppendCookie(myCookie);
<div class="container"> <h4 class="alert alert-info">ایجاد فاصله بین ستونها</h4> <div class="row"> <div class="col-lg-3 col-sm-4 alert alert-danger"> ستون اول </div> <div class="col-lg-8 col-lg-offset-1 col-sm-7 col-sm-offset-1 alert alert-success"> ستون دوم </div> </div> <!-- end row --> </div>
ممکنه راهنمائی بفرمائید
* نکته: پروژه انگیولار متریال ۲ در زمان نوشتن این مقاله به تازگی نسخه بتا ۵ را ارائه داده و همچنان در حال توسعه است. این بدان معنی است که ممکن است همه چیز به سرعت تغییر یابد.
مقدمه
انگیولار متریال ۲ همانند انگیولار متریال یک، تمامی المانهای مورد نیاز برای طراحی یک برنامه تک صفحهای را به راحتی فراهم میکند (هرچند تمامی المانهای آن در نسخه بتا پیاده سازی نشدهاند). خبر خوب اینکه، اکثر کامپوننتهای ارائه شده در انگیولار متریال ۲ از قالب راست به چپ پشتیبانی میکنند و اعمال این قالب به سادگی اضافه کردن خصوصیت dir یک المان به rtl است.
در صفحه گیتهاب انگیولار متریال ۲ آمدهاست که انگیولار متریال ۲، واسطهای کاربری با کیفیت بالا را ارائه میدهد و در ادامه منظورش را از «کیفیت بالا»، اینگونه بیان میکند:
تست تمامی
رفتارها توسط تست یکپارچگی (unit test ) و تست واحد ( integration test )
قابلیت
سفارشی سازی در چارچوب طراحی متریال
بهرهوری
بالا
کد
تمیز و مستندات خوب
شروع کار با انگیولار متریال ۲
قدم اول: نصب angular-material و hammerjs
برای شروع بایستی Angular Material و angular animations و hammer.js را توسط npm به صورت زیر نصب کنید.
npm install --save @angular/material @angular/animations
npm install --save hammerjs
angular/material@: بسته مربوط به انگیولار متریال دو را نصب خواهد کرد.
angular/animations@: این بسته امکاناتی جهت ساخت افکتهای ویژه هنگام تغییر صفحات، یا بارگذاری المنتها را از طریق کدهای css نوشته شده، به راحتی امکانپذیر میکند.
Hammerjs: برخی از کامپوننتهای موجود در انگیولار متریال ۲ وابسته به کتابخانه Hammerjs هستند. (از جمله md-slide-toggle و md-slider, mdTooltip)
"scripts": [ "../node_modules/hammerjs/hammer.min.js" ],
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { MaterialModule } from '@angular/material'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, FormsModule, HttpModule, MaterialModule, BrowserAnimationsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
قدم چهارم: افزودن تم و آیکون
همراه با نصب Angular Material تعدادی تم از قبل ساخته شده نیز نصب خواهند شد که شامل یکسری استایل با رنگهای مشخصی هستند. از جمله این تمها عبارتند از:
همچنین با استفاده از Material Design icons نیز با استفاده از تگ <md-icon> به آیکونهای متریال نیز میتوان دسترسی داشت.
برای افزودن آیکونهای متریال و همچنین انتخاب یک تم از قبل ساخته شده دو خط زیر را به فایل style.css اصلی برنامه اضافه کنید.
@import '~https://fonts.googleapis.com/icon?family=Material+Icons'; @import '~@angular/material/prebuilt-themes/deeppurple-amber.css';
نکتهای که در تگ <md-icon> وجود دارد این است که این تگ انواع فونتها و آیکونهای svg را نیز پشتیبانی میکند. استفاده از آیکونهای متریال یکی از قابلیتهای این تگ محسوب میشود.
برای اطلاعات بیشتر از نحوه ساخت تم سفارشی میتوانید این لینک را دنبال کنید.
قدم آخر: انگیولار متریال آماده است!
با انجام مراحل بالا اکنون میتوانید به راحتی از کامپوننتهای متریال استفاده کنید. کافی است کدهای زیر را به فایل app.component.html اضافه کنید و یک قالب ساده برای برنامه خود بسازید.
<md-sidenav-container> <md-sidenav #end align="end" opened="true" mode="side"> <md-toolbar color="accent"> <div> <md-toolbar-row> <img src="https://material.angular.io/favicon.ico" style="height:50px;margin-top: 2px; margin-bottom: 2px;"> <span> برنامه من </span> </md-toolbar-row> </div> </md-toolbar> <md-nav-list> <md-list-item [routerLink]="['/']"> <div> <div></div> <md-icon role="img" aria-label="home">home</md-icon> <span>خانه</span> </div> </md-list-item> </md-nav-list> <md-nav-list> <md-list-item [routerLink]="['/registries']"> <div> <div></div> <md-icon role="img" aria-label="forms">content_paste</md-icon> <span>فرم</span> </div> </md-list-item> </md-nav-list> <md-nav-list> <md-list-item href="/charts"> <div> <div></div> <md-icon role="img" aria-label="charts">show_chart</md-icon> <span>نمودارها</span> </div> </md-list-item> </md-nav-list> </md-sidenav> <header> <md-toolbar color="primary"> <button md-icon-button (click)="end.toggle()"> <md-icon>menu</md-icon> </button> <span>داشبورد</span> <button md-icon-button [md-menu-trigger-for]="menu"> <md-icon>person</md-icon> </button> </md-toolbar> <md-menu x-position="before" #menu="mdMenu"> <button md-menu-item>تنظیمات</button> <button md-menu-item>خروج</button> </md-menu> </header> <main> <router-outlet></router-outlet> </main> </md-sidenav-container> <span> <button md-fab> <md-icon>check circle</md-icon> </button> </span>
همچنین کدهای css زیر را به فایل اصلی style.css اضافه کنید.
html, body, material-app, md-sidenav-container, .my-content { margin: 0; direction: rtl; width: 100%; height: 100%; } .mat-button-toggle, .mat-button-base, .mat-button, .mat-raised-button, .mat-fab, .mat-icon-button, .mat-mini-fab, .mat-card, .mat-checkbox, .mat-input-container, .mat-list, .mat-menu-item, .mat-radio-button, .mat-select, .mat-list .mat-list-item .mat-list-item-content, .mat-nav-list .mat-list-item .mat-list-item-content, .mat-simple-snackbar, .mat-tab-label, .mat-slide-toggle-content, .mat-toolbar, .mat-tooltip { font-family: 'Iranian Sans', Tahoma !important; } md-sidenav { width: 225px; max-width: 70%; } md-sidenav md-nav-list { display: block; } md-sidenav md-nav-list :hover { background-color: rgb(250, 250, 250); } md-sidenav md-nav-list .md-list-item { cursor: pointer; } .side-navigation { padding-top: 0; } md-nav-list.side-navigation a[md-list-item] > .md-list-item > span.title { margin-right: 10px; } md-nav-list.side-navigation a[md-list-item] > .md-list-item { -webkit-font-smoothing: antialiased; letter-spacing: .14px; } md-list a[md-list-item] .md-list-item, md-list md-list-item .md-list-item, md-nav-list a[md-list-item] .md-list-item, md-nav-list md-list-item .md-list-item { display: flex; flex-direction: row; align-items: center; box-sizing: border-box; height: 48px; padding: 0 16px; } button.my-fab { position: absolute; right: 20px; bottom: 10px; } md-card { margin: 1em; } md-toolbar-row { justify-content: space-between; } .done { position: fixed; bottom: 20px; left: 20px; color: white; } md-nav-list.side-navigation a[md-list-item] { position: relative; } md-list a[md-list-item], md-list md-list-item, md-nav-list a[md-list-item], md-nav-list md-list-item { display: block; } md-list a[md-list-item], md-list md-list-item, md-nav-list a[md-list-item], md-nav-list md-list-item { color: #000; } md-nav-list a { text-decoration: none; color: inherit; } a { color: #039be5; text-decoration: none; -webkit-tap-highlight-color: transparent; } .no-padding { padding: 0 !important; }
به همین راحتی برنامه نمونه با طراحی متریال آماده است.