اگر به فایل css آن مراجعه کنید، یک چنین عرضهایی قابل مشاهده است:
.span12 { width: 940px; } .span1 { width: 60px; }
.row-fluid .span12 { width: 100%; *width: 99.94680851063829%; }
@gridColumns: 12; @gridColumnWidth: 60px; @gridGutterWidth: 20px;
.span12 { width: 940px; } .span1 { width: 60px; }
.row-fluid .span12 { width: 100%; *width: 99.94680851063829%; }
@gridColumns: 12; @gridColumnWidth: 60px; @gridGutterWidth: 20px;
... <div> <div> <input type="text" id="inputName" maxlength="15"> </div> <div> <button id="generateButton">Aye! Gimme a name!</button> </div> </div> ...
import 'dart:html'; ButtonElement genButton;
void main() { querySelector('#inputName').onInput.listen(updateBadge); genButton = querySelector('#generateButton'); genButton.onClick.listen(generateBadge); }
... void setBadgeName(String newName) { querySelector('#badgeName').text = newName; }
... void generateBadge(Event e) { setBadgeName('Meysam Khoshbakht'); }
void updateBadge(Event e) { String inputName = (e.target as InputElement).value; setBadgeName(inputName); }
void updateBadge(Event e) { String inputName = (e.target as InputElement).value; setBadgeName(inputName); if (inputName.trim().isEmpty) { // To do: add some code here. } else { // To do: add some code here. } }
void updateBadge(Event e) { String inputName = (e.target as InputElement).value; setBadgeName(inputName); if (inputName.trim().isEmpty) { genButton..disabled = false ..text = 'Aye! Gimme a name!'; } else { genButton..disabled = true ..text = 'Arrr! Write yer name!'; } }
گام چهارم: ایجاد کلاس PirateName
در این مرحله فقط کد مربوط به فایل dart را تغییر میدهیم. ابتدا کلاس PirateName را ایجاد میکنیم. با ایجاد نمونه ای از این کلاس، یک نام بصورت تصادفی انتخاب میشود و یا نامی بصورت اختیاری از طریق سازنده انتخاب میگردد.
نخست کتابخانه dart:math را به ابتدای فایل dart اضافه کنید
import 'dart:html'; import 'dart:math' show Random;
توضیحات
- با استفاده از کلمه کلیدی show، شما میتوانید فقط کلاسها، توابع و یا ویژگیهای مورد نیازتان را import کنید.
- کلاس Random یک عدد تصادفی را تولید میکند
در انتهای فایل کلاس زیر را تعریف کنید
... class PirateName { }
در داخل کلاس یک شی از کلاس Random ایجاد کنید
class PirateName { static final Random indexGen = new Random(); }
توضیحات
- با استفاده از static یک فیلد را در سطح کلاس تعریف میکنیم که بین تمامی نمونههای ایجاد شده از کلاس مشترک میباشد
- متغیرهای final فقط خواندنی میباشند و غیر قابل تغییر هستند.
- با استفاده از new میتوانیم سازنده ای را فراخوانی نموده و نمونه ای را از کلاس ایجاد کنیم
دو فیلد دیگر از نوع String و با نامهای _firstName و _appelation به کلاس اضافه میکنیم
class PirateName { static final Random indexGen = new Random(); String _firstName; String _appellation; }
متغیرهای خصوصی با (_) تعریف میشوند. Dart کلمه کلیدی private را ندارد.
دو لیست static به کلاس فوق اضافه میکنیم که شامل لیستی از name و appelation میباشد که میخواهیم آیتمی را بصورت تصادفی از آنها انتخاب کنیم.
class PirateName { ... static final List names = [ 'Anne', 'Mary', 'Jack', 'Morgan', 'Roger', 'Bill', 'Ragnar', 'Ed', 'John', 'Jane' ]; static final List appellations = [ 'Jackal', 'King', 'Red', 'Stalwart', 'Axe', 'Young', 'Brave', 'Eager', 'Wily', 'Zesty']; }
کلاس List میتواند شامل مجموعه ای از آیتمها میباشد که در Dart تعریف شده است.
سازنده ای را بصورت زیر به کلاس اضافه میکنیم
class PirateName { ... PirateName({String firstName, String appellation}) { if (firstName == null) { _firstName = names[indexGen.nextInt(names.length)]; } else { _firstName = firstName; } if (appellation == null) { _appellation = appellations[indexGen.nextInt(appellations.length)]; } else { _appellation = appellation; } } }
توضیحات
- سازنده تابعی همنام کلاس میباشد
- پارامترهایی که در {} تعریف میشوند اختیاری و Named Parameter میباشند. Named Parameterها پارمترهایی هستند که جهت مقداردهی به آنها در زمان فراخوانی، از نام آنها استفاده میشود.
- تابع nextInt() یک عدد صحیح تصادفی جدید را تولید میکند.
- جهت دسترسی به عناصر لیست از [] و شمارهی خانهی لیست استفاده میکنیم.
- ویژگی length تعداد آیتمهای موجود در لیست را بر میگرداند.
در این مرحله یک getter برای دسترسی به pirate name ایجاد میکنیم
class PirateName { ... String get pirateName => _firstName.isEmpty ? '' : '$_firstName the $_appellation'; }
توضیحات
- Getterها متدهای خاصی جهت دسترسی به یک ویژگی به منظور خواندن مقدار آنها میباشند.
- عملگر سه گانه :? دستور میانبر عبارت شرطی if-else میباشد
- $ یک کاراکتر ویژه برای رشتههای موجود در Dart میباشد و میتواند محتوای یک متغیر یا ویژگی را در رشته قرار دهد. در رشته '$_firstName the $_appellation' محتوای دو ویژگی _firstName و _appellation در رشته قرار گرفته و نمایش مییابند.
- عبارت (=> expr;) یک دستور میانبر برای { return expr; } میباشد.
تابع setBadgeName را بصورت زیر تغییر دهید تا یک پارامتر از نوع کلاس PirateName را به عنوان پارامتر ورودی دریافت نموده و با استفاده از Getter مربوط به ویژگی pirateName، مقدار آن را در badge name نمایش دهد.
void setBadgeName(PirateName newName) { querySelector('#badgeName').text = newName.pirateName; }
تابع updateBadge را بصورت زیر تغییر دهید تا یک نمونه از کلاس PirateName را با توجه به مقدار ورودی کاربر در فیلد input تولید نموده و تابع setBadgeName رافراخوانی نماید. همانطور که در کد مشاهده میکنید پارامتر ورودی اختیاری firstName در زمان فراخوانی با ذکر نام پارامتر قبل از مقدار ارسالی نوشته شده است. این همان قابلیت Named Parameter میباشد.
void updateBadge(Event e) { String inputName = (e.target as InputElement).value; setBadgeName(new PirateName(firstName: inputName)); ... }
تابع generateBadge را بصورت زیر تغییر دهید تا به جای نام ثابت Meysam Khoshbakht، از کلاس PirateName به منظور ایجاد نام استفاده کند. همانطور که در کد میبینید، سازندهی بدون پارامتر کلاس PirateName فراخوانی شده است.
void generateBadge(Event e) { setBadgeName(new PirateName()); }
همانند گام سوم برنامه را اجرا کنید و نتیجه را مشاهده نمایید.
private static string GetScript() { string path = AppDomain.CurrentDomain.BaseDirectory + @"Scripts\script.sql"; var file = new FileInfo(path); string script = file.OpenText().ReadToEnd(); return script; } private static void ExecuteScript() { string script = GetScript(); //split the script on "GO" commands var splitter = new[] {"\r\nGO\r\n"}; string[] commandTexts = script.Split(splitter, StringSplitOptions.RemoveEmptyEntries); foreach (string commandText in commandTexts) { using (var ctx = new DbContext()) { if (!string.IsNullOrEmpty(commandText)) { ctx.Database.ExecuteSqlCommand(commandText); } } } }
<input type="text" ng-model="newItemTitle"> <button type="button" ng-click="add()">افزودن</button> <ul> <li ng-repeat="item in items">{{item.title}}</li> </ul> <div ng-show="showMSG()">شما بیش از ۱۰ استان ثبت کرده اید</div>
$scope.newItemTitle=''; $scope.add=function(){ $scope.items.push({ title:$scope.newItemTitle }); } $scope.items=[ {title:'اردبیل'}, {title:'تهران'}, {title:'اصفهان'}, {title:'شیراز'}, {title:'مشهد'}, ]; $scope.showMSG=function(){ return $scope.items.length>10; }
ng-show="showMSG()" ng-if="showMSG()" ng-hide="showMSG()==false" ng-class="{'red',getResult()}" ng-style="{'width':getWidth()}"
<div ng-show="items.length>10">شما بیش از ۱۰ استان ثبت کرده اید</div>
$scope.maxItem=false'; $scope.add=function(){ $scope.items.push({ title:$scope.newItemTitle }); $scope.maxItem=$scope.items.length>10; }
<div ng-show="maxItem">شما بیش از ۱۰ استان ثبت کرده اید</div>
let x = 10;
let x: i32 = 10;
let x = 10; x = 20; //compile-time error
let mut x = 10; x = 20;
{ let x = 10; } // این متغیر خارج از این محدوده در دسترس نخواهد بود
fn main() { let x = 5; println!("The value of x is: {}", x); // خروجی برابر 5 است let x = "hello"; println!("The value of x is: {}", x); // خروجی برابر hello }
> npm install bootstrap --save > npm install ngx-bootstrap --save
"apps": [ { "styles": [ "../node_modules/bootstrap/dist/css/bootstrap.min.css", "styles.css" ],
import { PaginationModule } from "ngx-bootstrap"; @NgModule({ imports: [ PaginationModule.forRoot() ]
>ng g m SimpleGrid -m app.module --routing
>ng g c SimpleGrid/products-list
>ng g cl SimpleGrid/app-product
export class AppProduct { constructor( public productId: number, public productName: string, public price: number, public isAvailable: boolean ) {} }
>ng g cl SimpleGrid/PagedQueryModel
export class PagedQueryModel { constructor( public sortBy: string, public isAscending: boolean, public page: number, public pageSize: number ) {} }
>ng g cl SimpleGrid/PagedQueryResult
export class PagedQueryResult<T> { constructor(public totalItems: number, public items: T[]) {} }
>ng g cl SimpleGrid/GridColumn
export class GridColumn { constructor( public title: string, public propertyName: string, public isSortable: boolean ) {} }
>ng g s SimpleGrid/products-list -m simple-grid.module
toQueryString(obj: any): string { const parts = []; for (const key in obj) { if (obj.hasOwnProperty(key)) { const value = obj[key]; if (value !== null && value !== undefined) { parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(value)); } } } return parts.join("&"); }
[HttpGet("[action]")] public PagedQueryResult<Product> GetPagedProducts(ProductQueryViewModel queryModel)
http://localhost:5000/api/Product/GetPagedProducts?sortBy=productId&isAscending=true&page=2&pageSize=7
@Injectable() export class ProductsListService { private baseUrl = "api/Product"; constructor(private http: Http) {} getPagedProductsList( queryModel: PagedQueryModel ): Observable<PagedQueryResult<AppProduct>> { return this.http .get(`${this.baseUrl}/GetPagedProducts?${this.toQueryString(queryModel)}`) .map(res => { const result = res.json(); return new PagedQueryResult<AppProduct>( result.totalItems, result.items ); }); }
<table class="table table-striped table-hover table-bordered table-condensed"> <thead> <tr> <th class="text-center" style="width:3%">#</th> <th *ngFor="let column of columns" class="text-center"> <div *ngIf="column.isSortable" (click)="sortBy(column.propertyName)" style="cursor: pointer"> {{ column.title }} <i *ngIf="queryModel.sortBy === column.propertyName" class="glyphicon" [class.glyphicon-sort-by-order]="queryModel.isAscending" [class.glyphicon-sort-by-order-alt]="!queryModel.isAscending"></i> </div> <div *ngIf="!column.isSortable" style="cursor: pointer"> {{ column.title }} </div> </th> </tr> </thead>
export class ProductsListComponent implements OnInit { columns: GridColumn[] = [ new GridColumn("Id", "productId", true), new GridColumn("Name", "productName", true), new GridColumn("Price", "price", true), new GridColumn("Available", "isAvailable", true) ];
export class ProductsListComponent implements OnInit { itemsPerPage = 7; queryModel = new PagedQueryModel("productId", true, 1, this.itemsPerPage); sortBy(columnName) { if (this.queryModel.sortBy === columnName) { this.queryModel.isAscending = !this.queryModel.isAscending; } else { this.queryModel.sortBy = columnName; this.queryModel.isAscending = true; } this.getPagedProductsList(); } }
<tbody> <tr *ngFor="let item of queryResult.items; let i = index"> <td class="text-center">{{ itemsPerPage * (currentPage - 1) + i + 1 }}</td> <td class="text-center">{{ item.productId }}</td> <td class="text-center">{{ item.productName }}</td> <td class="text-center">{{ item.price | number:'.0' }}</td> <td class="text-center"> <input id="item-{{ item.productId }}" type="checkbox" [checked]="item.isAvailable" disabled="disabled" /> </td> </tr> </tbody> </table>
export class ProductsListComponent implements OnInit { itemsPerPage = 7; currentPage: number; numberOfPages: number; isLoading = false; queryModel = new PagedQueryModel("productId", true, 1, this.itemsPerPage); queryResult = new PagedQueryResult<AppProduct>(0, []); constructor(private productsListService: ProductsListService) {} ngOnInit() { this.getPagedProductsList(); } private getPagedProductsList() { this.isLoading = true; this.productsListService .getPagedProductsList(this.queryModel) .subscribe(result => { this.queryResult = result; this.isLoading = false; }); } }
<div align="center"> <pagination [maxSize]="8" [boundaryLinks]="true" [totalItems]="queryResult.totalItems" [rotate]="false" previousText="‹" nextText="›" firstText="«" lastText="»" (numPages)="numberOfPages = $event" [(ngModel)]="currentPage" (pageChanged)="onPageChange($event)"></pagination> </div> <pre class="card card-block card-header">Page: {{currentPage}} / {{numberOfPages}}</pre>
export class ProductsListComponent implements OnInit { itemsPerPage = 7; currentPage: number; numberOfPages: number; onPageChange(event: any) { this.queryModel.page = event.page; this.getPagedProductsList(); } }
<cdk-virtual-scroll-viewport></cdk-virtual-scroll-viewport>
npm install -g @angular/cli
ng new angular7-virtualScrolling
npm install @angular/cdk@latest
title = 'Angular 7 – Virtual Scrolling feature'; scrollItems: number[] = []; constructor() { for (let index = 0; index < 10000; index++) { this.scrollItems.push(index); } }
<div> <h4> {{this.title}} </h4> <cdk-virtual-scroll-viewport itemSize="100"> <div *cdkVirtualFor="let n of scrollItems">Item {{n}}</div> </cdk-virtual-scroll-viewport> </div>
overflow: hidden;
$(document).ready(function(){
$('.post-body img').each(function(){
var $img = $(this);
var src = $img.attr("src");
$img.attr({border:"0"}).wrap('<a target="_blank" alt="Click here to enlarge (opens new window)" title="Click here to enlarge (opens new window)" href="'+src+'" />');
});
});
public class MyHttpHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { } public bool IsReusable { get { return false; } } }
public class MyHttpHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { HttpResponse response = context.Response; HttpRequest request = context.Request; response.Write("Every Page has a some text like this"); } public bool IsReusable { get { return false; } } }
<system.web> <httpHandlers> <add verb="*" path="*.aspx" type="MyHttpHandler"/> </httpHandlers> </system.web>
<configuration> <system.web> <httpHandlers> <add name="myhttphandler" verb="*" path="*.aspx" type="MyHttpHandler"/> </httpHandlers> </system.web> </configuration>
گزینه Type که نام کلاس میباشد و اگر کلاس داخل یک فضای نام قرار گرفته باشد، باید اینطور نوشت : namespace.ClassName |
گزینه verb شامل مقادیری چون Get,Post,Head,Putو Delete میباشد و httphandler را فقط برای این نوع درخواستها اجرا میکند و در صورتیکه بخواهید چندتا از آنها را استفاده کنید، با , از هم جدا میشوند. مثلا Get,post و درصورتیکه همهی گزینهها را بخواهید علامت * را میتوان استفاده کرد. |
گزینهی path این امکان را به شما میدهد که مسیر و نوع فایلهایی را که قصد دارید روی آنها فقط اجرا شود، مشخص کنید و ما در قطعه کد بالا گفتهایم که تنها روی فایلهایی با پسوند aspx اجرا شود و چون مسیری هم ذکر نکردیم برای همهی مسیرها قابل اجراست. یکی از مزیتهای دادن پسوند این است که میتوانید پسوندهای اختصاصی داشته باشید. مثلا پسوند RSS برای فیدهای وب سایتتان. بسیاری از برنامه نویسان به جای استفاده از صفحات aspx از ashx استفاده میکنند که به مراتب سبکتر از aspx هست و شامل بخش ui نمیشود و نتیجه خروجی آن بر اساس کدی که مینویسید مشخص میشود که میتواند صفحه متنی یا عکس یا xml یا ... باشد. در اینجا در مورد ساخت صفحات ashx توضیح داده شده است. |
public class MyHttpHandler1 :IHttpHandler { public void ProcessRequest(HttpContext context) { HttpResponse response = context.Response; response.Write("this is httphandler1"); } public bool IsReusable { get { return false; } } } public class MyHttpHandler2 : IHttpHandler { public void ProcessRequest(HttpContext context) { HttpResponse response = context.Response; response.Write("this is httphandler2"); } public bool IsReusable { get { return false; } } }
public class MyFactory : IHttpHandlerFactory { public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTrasnlated) { } public void ReleaseHandler(IHttpHandler handler) { } }
Context | یک شی از کلاس httpcontext که دسترسی ما را برای اشیاء سروری چون response,request,session و... فراهم میکند. |
RequestType | مشخص میکند که درخواست صفحه به چه صورتی است. این گزینه برای مواردی است که verb بیش از یک مورد را حمایت میکند. برای مثال دوست دارید یک هندلر را برای درخواستهای Get ارسال کنید و هندلر دیگر را برای درخواستهای نوع Post |
URL | مسیر مجازی virtual Path صفحه صدا زده شده |
PathTranslated | مسیر فیزیکی صفحه درخواست کننده را ارسال میکند. |
public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTrasnlated) { string handlername = "MyHttpHandler1"; if(url.Substring(url.LastIndexOf("/")+1).StartsWith("t")) { handlername = "MyHttpHandler2"; } try { return (IHttpHandler) Activator.CreateInstance(Type.GetType(handlername)); } catch (Exception e) { throw new HttpException("Error: " + handlername, e); } } public void ReleaseHandler(IHttpHandler handler) { } }
موقعی که اینترفیس IHttpAsyncHandler را ارث بری کنید (این اینترفیس نیز از IHttpHandler ارث بری کرده است و دو متد اضافهتر دارد)، باید دو متد دیگر را نیز پیاده سازی کنید:در اعمالی که disk I/O و یا network I/O دارند، پردازش موازی و اعمال async به شدت مقیاس پذیری سیستم را بالا میبرند. به این ترتیب worker thread جاری (که تعداد آنها محدود است)، سریعتر آزاد شده و به worker pool بازگشت داده میشود تا بتواند به یک درخواست دیگر رسیده سرویس دهد. در این حالت میتوان با منابع کمتری، درخواستهای بیشتری را پردازش کرد.
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback callback, object obj) { } public void EndProcessRequest(IAsyncResult result) { }
public class AsynchOperation : IAsyncResult { private bool _completed; private Object _state; private AsyncCallback _callback; private HttpContext _context; bool IAsyncResult.IsCompleted { get { return _completed; } } WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } } Object IAsyncResult.AsyncState { get { return _state; } } bool IAsyncResult.CompletedSynchronously { get { return false; } } }
public AsynchOperation(AsyncCallback callback, HttpContext context, Object state) { _callback = callback; _context = context; _state = state; _completed = false; }
public void StartAsyncWork() { ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask),null); }
private void StartAsyncTask(Object workItemState) { _context.Response.Write("<p>Completion IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n"); _context.Response.Write("Hello World from Async Handler!"); _completed = true; _callback(this); }
context.Response.Write("<p>Begin IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n"); AsynchOperation asynch = new AsynchOperation(callback, context, obj); asynch.StartAsyncWork(); return asynch;
public class MyHttpHandler : IHttpAsyncHandler { public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback callback, object obj) { context.Response.Write("<p>Begin IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n"); AsynchOperation asynch = new AsynchOperation(callback, context, obj); asynch.StartAsyncWork(); return asynch; } public void EndProcessRequest(IAsyncResult result) { } public void ProcessRequest(HttpContext context) { throw new InvalidOperationException(); } public bool IsReusable { get { return false; } } } public class AsynchOperation : IAsyncResult { private bool _completed; private Object _state; private AsyncCallback _callback; private HttpContext _context; bool IAsyncResult.IsCompleted { get { return _completed; } } WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } } Object IAsyncResult.AsyncState { get { return _state; } } bool IAsyncResult.CompletedSynchronously { get { return false; } } public AsynchOperation(AsyncCallback callback, HttpContext context, Object state) { _callback = callback; _context = context; _state = state; _completed = false; } public void StartAsyncWork() { ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask),null); } private void StartAsyncTask(Object workItemState) { _context.Response.Write("<p>Completion IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n"); _context.Response.Write("Hello World from Async Handler!"); _completed = true; _callback(this); }
مایکروسافت در MSDN نوشته است که httphandlerها در واقع فرآیندهایی هستند (به این فرایندها بیشتر End Point میگویند) که در پاسخ به درخواستهای رسیده شده توسط asp.net application اجرا میشوند و بیشترین درخواست هایی هم که میرسد از نوع صفحات Aspx میباشد و موقعی که کاربری درخواست صفحهی aspx میکند هندلرهای مربوط به page اجرا میشوند.