مفاهیم برنامه نویسی ـ مروری بر کلاس و شیء
نصب کامپوننت Blazored TextEditor
ابتدا نیاز است بستهی نیوگت آنرا با اجرای دستور زیر، به پروژهی Blazor خود اضافه کرد:
dotnet add package Blazored.TextEditor
libman install quill --provider unpkg --destination wwwroot/lib/quill
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>BlazorServer.App</title> <base href="~/" /> <link href="lib/quill/dist/quill.snow.css" rel="stylesheet" /> <link href="lib/quill/dist/quill.bubble.css" rel="stylesheet" />
<script src="lib/quill/dist/quill.min.js"></script> <script src="_content/Blazored.TextEditor/quill-blot-formatter.min.js"></script> <script src="_content/Blazored.TextEditor/Blazored-BlazorQuill.js"></script> <script src="_framework/blazor.server.js"></script> </body>
و در آخر جهت سهولت کار با این کامپوننت میتوان فضای نام آنرا به فایل BlazorServer.App\_Imports.razor به صورت زیر اضافه کرد:
@using Blazored.TextEditor
استفاده از کامپوننت Blazored.TextEditor در کامپوننت HotelRoomUpsert.razor
میخواهیم در کامپوننت HotelRoomUpsert.razor مثال این سری، بجای کامپوننت InputTextArea مورد استفاده، از یک HTML Editor استفاده کنیم:
<div class="form-group"> <label>Details</label> @*<InputTextArea @bind-Value="HotelRoomModel.Details" class="form-control"></InputTextArea>*@ <BlazoredTextEditor @ref="@QuillHtml"> <ToolbarContent> <select class="ql-header"> <option selected=""></option> <option value="1"></option> <option value="2"></option> <option value="3"></option> <option value="4"></option> <option value="5"></option> </select> <span class="ql-formats"> <button class="ql-bold"></button> <button class="ql-italic"></button> <button class="ql-underline"></button> <button class="ql-strike"></button> </span> <span class="ql-formats"> <select class="ql-color"></select> <select class="ql-background"></select> </span> <span class="ql-formats"> <button class="ql-list" value="ordered"></button> <button class="ql-list" value="bullet"></button> </span> <span class="ql-formats"> <button class="ql-link"></button> </span> </ToolbarContent> <EditorContent> </EditorContent> </BlazoredTextEditor> </div>
- همانطور که ملاحظه میکنید، این تعریف به همراه یک ارجاع به وهلهای از آن نیز هست:
<BlazoredTextEditor @ref="@QuillHtml">
@code { private BlazoredTextEditor QuillHtml;
برای تغییر اندازه و مقدار placeholder پیشفرض آن، میتوان به صورت زیر عمل کرد:
<div class="form-group pb-4" style="height:250px;"> <label>Details</label> <BlazoredTextEditor @ref="@QuillHtml" Placeholder="Please enter the room's detail">
تنظیم و دریافت متن نمایشی HTML Editor
مطابق مستندات این کامپوننت، روش تنظیم متن نمایشی آن، به کمک متد LoadHTMLContent است. به همین جهت متد زیر را به کدهای کامپوننت جاری اضافه میکنیم:
private async Task SetHTMLAsync() { if(!string.IsNullOrEmpty(HotelRoomModel.Details)) { await QuillHtml.LoadHTMLContent(HotelRoomModel.Details); } }
protected override async Task OnInitializedAsync() { if (Id.HasValue) { // Update Mode Title = "Update"; HotelRoomModel = await HotelRoomService.GetHotelRoomAsync(Id.Value); await SetHTMLAsync(); } // ... }
private async Task HandleHotelRoomUpsert() { // ... // Create Mode HotelRoomModel.Details = await QuillHtml.GetHTML(); // ... }
مشکل! ادیتور در زمان ویرایش یک رکورد، اطلاعات پیشین را نمایش نمیدهد!
پس از اعمال تغییرات فوق، برنامه را اجرا میکنیم. سپس یک اتاق جدید را اضافه کرده و در لیست نمایش اتاقها، گزینهی ویرایش آنرا انتخاب میکنیم. در این حالت هرچند کار مقدار دهی HotelRoomModel.Details در زمان ثبت اطلاعات انجام شده، اما ... در زمان ویرایش چیزی نمایش داده نمیشود و تغییراتی را که به متد رویدادگردان OnInitializedAsync اضافه کردهایم، عمل نمیکنند.
در این مورد در قسمت بررسی چرخهی حیات کامپوننتها توضیحاتی ابتدایی ارائه شد:
«رویدادهای OnAfterRender و OnAfterRenderAsync
پس از هر بار رندر کامپوننت، این متدها فراخوانی میشوند. در این مرحله کار بارگذاری کامپوننت، دریافت اطلاعات و نمایش آنها به پایان رسیدهاست. یکی از کاربردهای آن، آغاز کامپوننتهای جاوا اسکریپتی است که برای کار، نیاز به DOM را دارند؛ مانند نمایش یک modal بوت استرپی.»
بنابراین در این حالت خاص که ادیتور جاوا اسکریپتی مورد استفاده، پس از رندر کامل UI نمایش داده میشود، قرار دادن متد SetHTML در روال رویدادگردان OnInitializedAsync کار نخواهد کرد و باید آنرا به روال رویدادگردان OnAfterRender انتقال دهیم:
protected override async Task OnAfterRenderAsync(bool firstRender) { await SetHTMLAsync(); }
private async Task SetHTMLAsync() { if(!string.IsNullOrEmpty(HotelRoomModel.Details)) { await QuillHtml.LoadHTMLContent(HotelRoomModel.Details); StateHasChanged(); } }
مشکل! اگر در این حالت سعی کنیم متنی را در ادیتور وارد کنیم، میسر نیست و همچنین CPU Usage سیستم به 100 درصد رسیدهاست!
علت اینجا است که فراخوانی StateHasChanged، هر چند سبب رندر مجدد UI میشود، اما چون در پایان کار رندر قرار داریم، یک حلقهی بینهایت را سبب خواهد شد. به همین جهت باید در متد OnAfterRenderAsync، بر اساس پارامتر firstRender، از رندرهای بعدی جلوگیری کرد:
protected override async Task OnAfterRenderAsync(bool firstRender) { if (!firstRender) { return; } while (true) { try { await SetHTMLAsync(); break; } catch { await Task.Delay(100); // Quill needs some time to load } } }
کدهای کامل این مطلب را از اینجا میتوانید دریافت کنید: Blazor-5x-Part-20.zip
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace FormValidationWithBootstrap.Models { [Table("Product")] public class ProductModel { [Key] public int Id { get; set; } [Required(ErrorMessage = "{0} یک فیلد اجباری است و باید آن را وارد کنید.")] [StringLength(50, ErrorMessage = "طول {0} باید کمتر از {1} کاراکتر باشد.")] [Display(Name = "نام کالا")] public string Name { get; set; } [Required(ErrorMessage = "{0} یک فیلد اجباری است و باید آن را وارد کنید.")] [Display(Name = "قیمت")] [DataType(DataType.Currency)] public double Price { get; set; } [Required(ErrorMessage = "{0} یک فیلد اجباری است و باید آن را وارد کنید.")] [Display(Name = "موجودی")] public int Qty { get; set; } } }
using System.Web.Mvc; using FormValidationWithBootstrap.Models; namespace FormValidationWithBootstrap.Controllers { public class ProductController : Controller { // GET: Product public ActionResult Index() { return View(); } public ActionResult New() { return View(); } [HttpPost] public ActionResult New(ProductModel product) { if (!ModelState.IsValid) return View(product); if (product.Name != "پفک") { ModelState.AddModelError("", "لطفا مشکلات را برطرف کنید!"); ModelState.AddModelError("Name", "فقط محصولی با نام پفک قابل ثبت است :)"); return View(product); } // todo:save... return RedirectToAction("Index"); } } }
@model FormValidationWithBootstrap.Models.ProductModel @{ ViewBag.Title = "New"; } <h2>کالای جدید</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div> <hr /> @Html.ValidationSummary(true, "", new { @class = "alert alert-danger" }) <div> @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) <div> @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) </div> </div> <div> @Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" }) <div> @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" }) </div> </div> <div> @Html.LabelFor(model => model.Qty, htmlAttributes: new { @class = "control-label col-md-2" }) <div> @Html.EditorFor(model => model.Qty, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Qty, "", new { @class = "text-danger" }) </div> </div> <div> <div> <input type="submit" value="ثبت" /> <input type="reset" value="ریست" /> @Html.ActionLink("بازگشت به لیست", "Index", "Product", null, new {@class="btn btn-default"}) </div> </div> </div> }
@section Scripts { @Scripts.Render("~/bundles/jqueryval") <script> // override jquery validate plugin defaults $.validator.setDefaults({ highlight: function (element) { $(element).closest('.form-group').addClass('has-error'); }, unhighlight: function (element) { $(element).closest('.form-group').removeClass('has-error').addClass('has-success'); }, errorElement: 'span', errorClass: 'help-block', errorPlacement: function (error, element) { if (element.parent('.input-group').length) { error.insertAfter(element.parent()); } else { error.insertAfter(element); } } }); $(function () { $('form').each(function () { $(this).find('div.form-group').each(function () { if ($(this).find('span.field-validation-error').length > 0) { $(this).addClass('has-error'); } }); }); }); </script> }
بسیاری از مواقع پیش میآید که در سایت خود بخواهیم کادری داشته باشیم که با کلیک بروی آن ظاهر و با کلیک دوباره بروی آن محو شود. مانند تصویر زیر
سپس با کلیک بروی قسمت مشخص شده از تصویر بالا تصویر مانند زیر ظاهر شود.
در این نوشته قصد داریم کادری به این صورت حالا به هر منظوری طراحی نماییم.
برای کار سه قسمت کد داریم:
- کدهای طراحی قسمت مورد نظر در صفحه وب
- نوشتن کدهای CSS مربوطه
- نوشتن کدهای jQuery
در مرحله اول ابتدا صفحه وب خود را به نحو زیر ایجاد مینماییم.
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>کادر لغزان با jQuery</title> <script src="Scripts/jquery-1.7.1.min.js"></script> <link href="CSS/site.css" rel="stylesheet" /> </head> <body> <div id="loginPanel"> <div style="height: auto;" id="login"> <div> <div> <br /> محتویات دلخواه خود را در این قسمت قرار دهید </div> </div> <div><a href="#" id="closeLogin"></a></div> </div> <div id="container"> <div id="top"> <!-- login --> <ul> <li> </li> <li><a id="toggleLogin" href="#">پانل باز شو</a></li> </ul> <!-- / login --> </div> <!-- / top --> </div> </div> <div id="main"> محتویات سایت در این قسمت قرار میگیرد </div> </body> </html>
body { margin:0; padding:0; width:100%; background: #e9e9e9 url(images/header_bg.gif) top repeat-x; direction: rtl; } html { padding:0; margin:0; } #main {margin-top: 100px;} #loginPanel { margin: 0px; position: absolute; overflow: hidden; height: auto; z-index: 3000; width: 100%; top: 0px; color: #fff; } #top { background: url(images/login_top.jpg) repeat-x 0 0; height: 38px; position: relative; } #top ul.login { display: block; position: relative; float: right; clear: right; height: 38px; width: auto; margin: 0; right: 150px; color: white; text-align: center; background: url(images/login_r.png) no-repeat right 0; padding-right: 45px; } #top ul.login li.left { background: url(images/login_l.png) no-repeat left 0; height: 38px; width: 45px; padding: 0; margin: 0; display: block; float: left; } #top ul.login li { text-align: left; padding: 0 6px; display: block; float: left; height: 38px; background: url(images/login_m.jpg) repeat-x 0 0; } #top ul.login li a { color: #fff; text-decoration: none; } #top ul.login li a:hover { color: #ff0000; text-decoration: none; } #login { width: 100%; color: white; background: #1E1E1E; overflow: hidden; position: relative; z-index: 3; height: 0px; } #login a { text-decoration: none; color: #fff; } #login a:hover { color: white; text-decoration: none; } #login .loginContent { width: 900px; height: 80px; margin: 0 auto; padding-top: 25px; text-align: right; } #login .loginClose { display: block; position: absolute; right: 15px; top: 10px; width: 70px; text-align: left; } #login .loginClose a { display: block; width: 100%; height: 20px; background: url(images/button_close.jpg) no-repeat right 0; padding-right: 10px; border: none; color: white; } #login .loginClose a:hover { background: url(images/button_close.jpg) no-repeat right -20px; } .cen { text-align: center;} .w_100p{ width: 100%;}
<script type="text/javascript"> $(document).ready(function () { $("#login").hide(0); $("#toggleLogin").click(function () { $("#login").slideToggle("slow"); }); $("#closeLogin").click(function () { $("#login").slideUp("slow"); }); }); </script>
بررسی سیستم جدید گرید بوت استرپ 3
<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>
ممکنه راهنمائی بفرمائید
اضافه کردن دکمهی More info به صفحهی About و مدیریت کلیک بر روی آن
فایل Scripts\Templates\about.hbs را گشوده و سپس محتوای فعلی آن را به نحو ذیل تکمیل کنید:
<h2>About Ember Blog</h2> <p>Bla bla bla!</p> <button class="btn btn-primary" {{action 'showRealName' }}>more info</button>
به همین جهت فایل جدید Scripts\Controllers\about.js را در پوشهی کنترلرهای سمت کاربر اضافه کنید (نام آن با نام مسیریابی یکی است)؛ با این محتوا:
Blogger.AboutController = Ember.Controller.extend({ actions: { showRealName: function () { alert("You clicked at showRealName of AboutController."); } } });
در ادامه این خاصیت را با تهیه یک زیرکلاس از کلاس پایه Controller تهیه شده توسط ember.js مقدار دهی میکنیم. به این ترتیب به کلیه امکانات این کلاس پایه دسترسی خواهیم داشت؛ به علاوه میتوان ویژگیهای سفارشی را نیز به آن افزود. برای مثال در اینجا در قسمت actions آن، دقیقا مطابق نام اکشنی که در فایل about.hbs تعریف کردهایم، یک متد جدید اضافه شدهاست.
پس از تعریف کنترلر about.js نیاز است مدخل متناظر با آنرا به فایل index.html برنامه نیز در انتهای تعاریف موجود، اضافه کرد:
<script src="Scripts/Controllers/about.js" type="text/javascript"></script>
اکنون یکبار برنامه را اجرا کرده و در صفحهی about بر روی دکمهی more info کلیک کنید.
اضافه کردن دکمهی ارسال پیام خصوصی به صفحهی Contact و مدیریت کلیک بر روی آن
در ادامه به قالب فعلی Scripts\Templates\contact.hbs یک دکمه را جهت ارسال پیام خصوصی اضافه میکنیم.
<h1>Contact</h1> <div class="row"> <div class="col-md-6"> <p> Want to get in touch? <ul> <li>{{#link-to 'phone'}}Phone{{/link-to}}</li> <li>{{#link-to 'email'}}Email{{/link-to}}</li> </ul> </p> <p> Or, click here to send a secret message: </p> <button class="btn btn-primary" {{action 'sendMessage' }}>Send message</button> </div> <div class="col-md-6"> {{outlet}} </div> </div>
Blogger.ContactController = Ember.Controller.extend({ actions: { sendMessage: function () { var message = prompt('Type your message here:'); } } });
<script src="Scripts/Controllers/contact.js" type="text/javascript"></script>
نمایش تصویری تعاملی در صفحهی about
تا اینجا با نحوهی تعریف اکشنها در قالبها و مدیریت آنها توسط کنترلرهای متناظر آشنا شدیم. در ادامه قصد داریم با اصول binding اطلاعات در ember.js آشنا شویم. برای مثال فرض کنید میخواهیم دکمهای را در صفحهی about قرار داده و با کلیک بر روی آن، لوگوی ember.js را که به صورت یک تصویر مخفی در صفحه قرار دارد، نمایان کنیم. برای اینکار نیاز است خاصیتی را در کنترلر متناظر، تعریف کرده و سپس آنرا به template جاری bind کرد.
برای این منظور فایل Scripts\Templates\about.hbs را گشوده و تعاریف موجود آنرا به نحو ذیل تکمیل کنید:
<h2>About Ember Blog</h2> <p>Bla bla bla!</p> <button class="btn btn-primary" {{action 'showRealName' }}>more info</button> {{#if isAuthorShowing}} <button class="btn btn-warning" {{action 'hideAuthor' }}>Hide Image</button> <p><img src="Content/images/ember-productivity-sm.png"></p> {{else}} <button class="btn btn-info" {{action 'showAuthor' }}>Show Image</button> {{/if}}
کنترلر about (فایل Scripts\Controllers\about.js) جهت مدیریت این خاصیت جدید، به همراه دو اکشن تعریف شده، اینبار به نحو ذیل تغییر خواهد یافت:
Blogger.AboutController = Ember.Controller.extend({ isAuthorShowing: false, actions: { showRealName: function () { alert("You clicked at showRealName of AboutController."); }, showAuthor: function () { this.set('isAuthorShowing', true); }, hideAuthor: function () { this.set('isAuthorShowing', false); } } });
سپس در دو متد showAuthor و hideAuthor که به اکشنهای دو دکمهی جدید تعریف شده در قالب about متصل خواهند شد، نحوهی تغییر مقدار خاصیت isAuthorShowing را توسط متد set ملاحظه میکنید.
این قسمت مهمترین تفاوت ember.js با jQuery است. در jQuery مستقیما المانهای صفحه در همانجا تغییر داده میشوند. در ember.js منطق مدیریت کنندهی رابط کاربری و کدهای قالب متناظر با آن از هم جدا شدهاند تا بتوان یک برنامهی بزرگ را بهتر مدیریت کرد. همچنین در اینجا مشخص است که هر قسمت و هر فایل، چه ارتباطی با سایر اجزای تعریف شده دارد و چگونه به هم متصل شدهاند و اینبار شاهد انبوهی از کدهای جاوا اسکریپتی مخلوط بین المانهای HTML صفحه نیستیم.
نمایش پیامی به کاربر پس از ارسال پیام خصوصی در صفحهی تماس با ما
قصد داریم ویژگی مشابهی را به صفحهی contact نیز اضافه کنیم. اگر کاربر بر روی دکمهی ارسال پیام کلیک کرد، پیام تشکری به همراه عددی ویژه به او نمایش خواهیم داد.
برای اینکار قالب Scripts\Templates\contact.hbs را به نحو ذیل تکمیل کنید:
<h1>Contact</h1> <div class="row"> <div class="col-md-6"> <p> Want to get in touch? <ul> <li>{{#link-to 'phone'}}Phone{{/link-to}}</li> <li>{{#link-to 'email'}}Email{{/link-to}}</li> </ul> </p> {{#if messageSent}} <p> Thank you. Your message has been sent. Your confirmation number is {{confirmationNumber}}. </p> {{else}} <p> Or, click here to send a secret message: </p> <button class="btn btn-primary" {{action 'sendMessage' }}>Send message</button> {{/if}} </div> <div class="col-md-6"> {{outlet}} </div> </div>
برای تعریف منطق مرتبط با این خواص، به کنترلر contact واقع در فایل Scripts\Controllers\contact.js مراجعه کرده و آنرا به نحو ذیل تغییر میدهیم:
Blogger.ContactController = Ember.Controller.extend({ messageSent: false, actions: { sendMessage: function () { var message = prompt('Type your message here:'); if (message) { this.set('confirmationNumber', Math.round(Math.random() * 100000)); this.set('messageSent', true); } } } });
بنابراین به صورت خلاصه، کار کنترلر، مدیریت منطق نمایشی برنامه است و برای اینکار حداقل دو مکانیزم را ارائه میدهد: اکشنها و خواص. اکشنها بیانگر نوعی رفتار هستند؛ برای مثال نمایش یک popup و یا تغییر مقدار یک خاصیت. مقدار خواص را میتوان مستقیما در صفحه نمایش داد و یا از آنها جهت پردازش عبارات شرطی و نمایش قسمت خاصی از قالب جاری نیز میتوان کمک گرفت.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید:
EmberJS03_02.zip
اگر علاقمند باشید که syntax highlighting را به سورس کدهای ارسالی در بلاگر اضافه کنید، روش کار به صورت زیر است:
از آنجائیکه دسترسی به سرور و راه حلهای سمت سرور را نخواهیم داشت، تنها راه حل باقیمانده استفاده از روشهای سمت کلاینت است. کتابخانه زیر این امر را میسر میسازد:
http://code.google.com/p/syntaxhighlighter/
این کتابخانه، کار Syntax highlighting سمت کلاینت را با استفاده از JavaScript انجام میدهد.
پس از دریافت آن (احتمالا به یک پروکسی نیاز پیدا خواهید کرد ...)، فایلها را در یک سرور قرار دهید. (برای مثال در Google pages)
سپس به قسمت ویرایش html قالب سایت مراجعه کنید و کدهای زیر را به آن اضافه نمائید (درصورت نیاز مسیرهای فایلها را ویرایش کنید):
<link href='http://vahid.nasiri.googlepages.com/SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>
<script src='http://vahid.nasiri.googlepages.com/shCore.js' type='text/javascript'/>
<script src='http://vahid.nasiri.googlepages.com/shBrushCpp.js' type='text/javascript'/>
<script src='http://vahid.nasiri.googlepages.com/shBrushCSharp.js' type='text/javascript'/>
<script src='http://vahid.nasiri.googlepages.com/shBrushCss.js' type='text/javascript'/>
<script src='http://vahid.nasiri.googlepages.com/shBrushJava.js' type='text/javascript'/>
<script src='http://vahid.nasiri.googlepages.com/shBrushJScript.js' type='text/javascript'/>
<script src='http://vahid.nasiri.googlepages.com/shBrushSql.js' type='text/javascript'/>
<script src='http://vahid.nasiri.googlepages.com/shBrushXml.js' type='text/javascript'/>
<script class='javascript'>
//<![CDATA[
function FindTagsByName(container, name, Tag)
{
var elements = document.getElementsByTagName(Tag);
for (var i = 0; i < elements.length; i )
{
if (elements[i].getAttribute("name") == name)
{
container.push(elements[i]);
}
}
}
var elements = [];
FindTagsByName(elements, "code", "pre");
FindTagsByName(elements, "code", "textarea");
for(var i=0; i < elements.length; i ) {
if(elements[i].nodeName.toUpperCase() == "TEXTAREA") {
var childNode = elements[i].childNodes[0];
var newNode = document.createTextNode(childNode.nodeValue.replace(/<br\s*\/?>/gi,'\n'));
elements[i].replaceChild(newNode, childNode);
}
else if(elements[i].nodeName.toUpperCase() == "PRE") {
brs = elements[i].getElementsByTagName("br");
for(var j = 0, brLength = brs.length; j < brLength; j ) {
var newNode = document.createTextNode("\n");
elements[i].replaceChild(newNode, brs[0]);
}
}
}
// dp.SyntaxHighlighter.ClipboardSwf =
//"http://vahid.nasiri.googlepages.com/clipboard.swf";
dp.SyntaxHighlighter.HighlightAll("code");
//]]>
</script>
</div></div> <!-- end outer-wrapper -->
<div align="left" dir="ltr">
<pre name='code' language='sql'>
--get login time
SELECT login_time FROM master..sysprocesses WHERE spid = 1
</pre>
</div>
--get login time
SELECT login_time FROM master..sysprocesses WHERE spid = 1
ماخذ:
http://developertips.blogspot.com/2007/08/syntaxhighlighter-on-blogger.html
<script src="cordova.js"></script>
مثال برای اندروید
(function () { "use strict"; document.addEventListener( 'deviceready', onDeviceReady.bind( this ), false ); function onDeviceReady() { // Handle the Cordova pause and resume events document.addEventListener( 'pause', onPause.bind( this ), false ); document.addEventListener('resume', onResume.bind(this), false); document.addEventListener('menubutton', onMenuButton.bind(this), false); document.addEventListener('backbutton', onBackButton.bind(this), false); //document.addEventListener('searchbutton', onResume.bind(this), false); //document.addEventListener('endcallbutton', onResume.bind(this), false); //document.addEventListener('offline', onResume.bind(this), false); //document.addEventListener('online', onResume.bind(this), false); //document.addEventListener('startcallbutton', onResume.bind(this), false); //document.addEventListener('volumedownbutton', onResume.bind(this), false); //document.addEventListener('volumeupbutton', onResume.bind(this), false); // TODO: Cordova has been loaded. Perform any initialization that requires Cordova here. }; function onPause() { // TODO: This application has been suspended. Save application state here. alert("paused"); }; function onResume() { alert("resume"); }; function onMenuButton() { alert("menu"); }; function onBackButton() { alert("back button"); }; } )();
.در مقالات آینده از افزونههای موجود، برای مدیریت رخدادهای باتری سیستم استفاده خواهیم کرد
jQuery Mobile
Phones/Tablets
Android 1.6+
BlackBerry 5+
iOS 3+
Windows Phone 7
WebOS 1.4+
Symbian (Nokia S60)
Firefox Mobile Opera Mobile 11+
Opera Mini 5+
Desktop browsers
Chrome 11+
Firefox 3.6+
Internet Explorer 7+
Safari
برای نصب jQuery Mobile کافی است دستورات زیر را در package manager console ویژوال استودیو استفاده کنید:
PM>install-package jquery
PM>install-package jquery.mobile.rtl
بعد از دانلود فایلهای مورد نظر خود، فولدری بنام jquery.mobile.rtl در ریشه پروژه ایجاد خواهد شد. به ترتیب فایل های rtl.jquery.mobile-1.4.0.css و rtl.jquery.mobile-1.4.0.js موجود در زیر شاخههای فلدر مذکور را به head و آخر body فایل index.html اضافه کنید.
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>CordovaApp01</title> <!-- CordovaApp01 references --> <link href="css/index.css" rel="stylesheet" /> <link href="jquery.mobile.rtl/css/themes/default/rtl.jquery.mobile-1.4.0.css" rel="stylesheet" /> </head> <body> <div data-role="page" id="page1"> <div data-role="header"> <h1>اولین برنامه</h1> </div> <div data-role="content"> <p>سلام من محتوای اولین برنامه هستم</p> </div> <div data-role="footer"> <h1>من فوتر هستم</h1> </div> </div> <!-- Cordova reference, this is added to your app when it's built. --> <script src="scripts/jquery-2.1.3.min.js"></script> <script src="cordova.js"></script> <script src="scripts/platformOverrides.js"></script> <script src="scripts/index.js"></script> <script src="jquery.mobile.rtl/js/rtl.jquery.mobile-1.4.0.js"></script> </body> </html>
نتیجهی نهایی به شکل زیر خواهد بود:
در مقالهی بعد به استفاده از pluginها خواهیم پرداخت.
ادامه دارد...
WAS یا Windows Process Activation Service
پیکربندی مدیریتی در WAS
- Global configuration information
- Protocol configuration information for both HTTP and non-HTTP protocols
- Application pool configuration, such as the process account information
- Site configuration, such as bindings and applications
- Application configuration, such as the enabled protocols and the application pools to which the applications belong
مدیریت پروسهها Process Managment
نکته: از آنجایی که WAS هم پروسههای http و هم non-http را مدیریت میکند، پس میتوانید از یک applicatio pool برای چندین protocol استفاده کنید. به عنوان مثال شما یکی سرویس XML دارید که میتوانید از آن برای سرویس دهی به پروتوکلهای Http و net.tcp بهره بگیرید.
ماژولها در IIS
ماژولهای کد ماشین یا native
جدول ماژولهای HTTP
نام ماژول | توضیحات | نام فایل منبع |
CustomErrorModule | موقعی که هنگام response، کد خطایی تولید میگردد، پیام خطا را پیکربندی و سپس ارسال میکند. | Inetsrv\Custerr.dll |
HttpRedirectionModule | تنظمیات redirection برای درخواستهای http را در دسترس قرار میدهد. | Inetsrv\Redirect.dll |
ProtocolSupportModule | انجام عملیات مربوط به پروتوکلها بر عهده این ماژول است؛ مثل تنظیم کردن قسمت هدر برای response. | Inetsrv\Protsup.dll |
RequestFilteringModule | این ماژول از IIS 7.5 به بعد اضافه شد. درخواستها را فیلتر میکند تا پروتوکل و رفتار محتوا را کنترل کند. | Inetsrv\modrqflt.dll |
WebDAVModule | این ماژول از IIS 7.5 به بعد اضافه شد. امنیت بیشتر در هنگام انتشار محتوا روی HTTP SSL | Inetsrv\WebDAV.dll |
ماژولهای امنیتی
نام ماژول | توضیحات | نام فایل منبع |
AnonymousAuthenticationModule | موقعی که هیچ کدام از عملیات authentication با موفقیت روبرو نشود، عملیات Anonymous authentication انجام میشود. | Inetsrv\Authanon.dll |
BasicAuthenticationModule | عمل ساده و اساسی authentication را انجام میدهد. | Inetsrv\Authbas.dll |
CertificateMappingAuthenticationModule | انجام عمل Certificate Mapping authentication در Active Directory | Inetsrv\Authcert.dll |
DigestAuthenticationModule | Digest authentication | Inetsrv\Authmd5.dll |
IISCertificateMappingAuthenticationModule | همان Certificate Mapping authentication ولی اینبار با IIS Certificate . | Inetsrv\Authmap.dll |
RequestFilteringModule | عملیات اسکن URL از قبیل نام صفحات و دایرکتوریها ، توع verb و یا کاراکترهای مشکوک و خطرآفرین | Inetsrv\Modrqflt.dll |
UrlAuthorizationModule | عمل URL authorization | Inetsrv\Urlauthz.dll |
WindowsAuthenticationModule | عمل NTLM integrated authentication | Inetsrv\Authsspi.dll |
IpRestrictionModule | محدود کردن IPهای نسخه 4 لیست شده در IP Security در قسمت پیکربندی | Inetsrv\iprestr.dll |
ماژولهای محتوا
نام ماژول | توضیحات | نام فایل منبع |
CgiModule | ایجاد پردازشهای (Common Gateway Interface (CGI به منظور ایجاد خروجی response | Inetsrv\Cgi.dll |
DefaultDocumentModule | تلاش برای ساخت یک سند پیش فرض برای درخواست هایی که دایرکتوری والد ارسال میشود | Inetsrv\Defdoc.dll |
DirectoryListingModule | لیست کردن محتوای یک دایرکتوری | Inetsrv\dirlist.dll |
IsapiModule | میزبانی فایل های ISAPI | Inetsrv\Isapi.dll |
IsapiFilterModule | پشتیبانی از فیلتر های ISAPI | Inetsrv\Filter.dll |
ServerSideIncludeModule | پردازش کدهای include شده سمت سرور | Inetsrv\Iis_ssi.dll |
StaticFileModule | ارائه فایلهای ایستا | Inetsrv\Static.dll |
FastCgiModule | پشتبانی از CGI | Inetsrv\iisfcgi.dll |
ماژولهای فشرده سازی
DynamicCompressionModule | فشرده سازی پاسخ response با gzip | Inetsrv\Compdyn.dll |
StaticCompressionModule | فشرده سازی محتوای ایستا | Inetsrv\Compstat.dll |
ماژولهای کش کردن
FileCacheModule | تهیه کش در مد کاربری برای فایلها. | Inetsrv\Cachfile.dll |
HTTPCacheModule | تهیه کش مد کاربری و مد کرنل برای http.sys | Inetsrv\Cachhttp.dll |
TokenCacheModule | تهیه کش مد کاربری بر اساس جفت نام کاربری و یک token که توسط Windows user principals تولید شده است. | Inetsrv\Cachtokn.dll |
UriCacheModule | تهیه یک کش مد کاربری از اطلاعات URL | Inetsrv\Cachuri.dll |
ماژولهای عیب یابی و لاگ کردن
CustomLoggingModule | بارگزاری ماژولهای خصوصی سازی شده جهت لاگ کردن | Inetsrv\Logcust.dll |
FailedRequestsTracingModule | برای ردیابی درخواستهای ناموفق | Inetsrv\Iisfreb.dll |
HttpLoggingModule | دریافت اطلاعات و پردازش وضعیت http.sys برای لاگ کردن | Inetsrv\Loghttp.dll |
RequestMonitorModule | ردیابی درخواست هایی که در حال حاضر در پروسههای کارگر در حال اجرا هستند و گزارش اطلاعاتی در مورد وضعیت اجرا و کنترل رابط برنامه نویسی کاربردی. | Inetsrv\Iisreqs.dll |
TracingModule | گزارش رخدادهای Microsoft Event Tracing for Windows یا به اختصار ETW | Inetsrv\Iisetw.dll |
ماژولهای مدیریتی و نظارتی بر کل ماژولها
ManagedEngine | مدیرتی بر ماژولهای غیر native که در پایین قرار دارند. | Microsoft.NET\Framework\v2.0.50727\webengine.dll |
ConfigurationValidationModule | اعتبارسنجی خطاها، مثل موقعی که برنامه در حالت integrated اجرا شده و ماژولها یا هندلرها در system.web تعریف شدهاند. | Inetsrv\validcfg.dll |
ماژول | توضیحات | منبع |
AnonymousIdentification | مدیریت منابع تعیین هویت برای کاربران ناشناس مانند asp.net profile | System.Web.Security.AnonymousIdentificationModule |
DefaultAuthentication | اطمینان از وجود شی Authentication در context مربوطه | System.Web.Security.DefaultAuthenticationModule |
FileAuthorization | تایید هویت کاربر برای دسترسی به فایل درخواست | System.Web.Security.FileAuthorizationModule |
FormsAuthentication | با این قسمت که باید کاملا آشنا باشید؛ برای تایید هویت کاربر | System.Web.Security.FormsAuthenticationModule |
OutputCache | مدیریت کش | System.Web.Caching.OutputCacheModule |
Profile | مدیریت پروفایل کاربران که تنظیماتش را در یک منبع دادهای چون دیتابیس ذخیره و بازیابی میکند. | System.Web.Profile.ProfileModule |
RoleManager | مدیریت نقش و سمت کاربران | System.Web.Security.RoleManagerModule |
Session | مدیریت session ها | System.Web.SessionState.SessionStateModule |
UrlAuthorization | آیا کاربر جاری حق دسترسی به URL درخواست را دارد؟ | System.Web.Security.UrlAuthorizationModule |
UrlMappingsModule | تبدیل یک Url واقعی به یک Url کاربرپسند | System.Web.UrlMappingsModule |
WindowsAuthentication | شناسایی و تایید و هویت یک کاربر بر اساس لاگین او به ویندوز | System.Web.Security.WindowsAuthenticationModule |