نظرات مطالب
نظرات مطالب
مرور چند تجربه کوتاه با Microsoft virtual pc
نقل قولی از متن بالا:
"... حتما از منوی action گزینه install or update virtual machine additions را انتخاب کنید تا کارآیی سیستم عامل مجازی را بهبود بخشید. حداقل فایده آن ..."
"... حتما از منوی action گزینه install or update virtual machine additions را انتخاب کنید تا کارآیی سیستم عامل مجازی را بهبود بخشید. حداقل فایده آن ..."
در این قسمت به بحث رویدادها میپردازیم و اینکه به چه صورتی میتوانیم از آنها درون پروژه استفاده کنیم. فریمورک Vue.js در عین سادگی میتواند نیاز شما را برآورده کرده و به نحو مطلوبی خروجی مناسبی را بدون هیچ دردسری، به شما تحویل دهد.
حال باید رویداد هدایت شود که از تگ a استفاده شده است. به صورت زیر:
لازم به اشاره است که جهت معرفی رویدادی به صفحه دیگر باید از دستور v-on که vuejs در اختیار ما قرار داده است، استفاده کرد و ما نیز چنین کدی را نوشتهایم و صفحه مورد نظر را ارجاع دادهایم.
رویدادها یا همان eventها به ما این اختیار را میدهند که بتوانیم عمل خاصی را بر روی یک صفحه یا قسمتهای مختلف درون پروژه اعمال کنیم و کاملا شبیه رویدادهایی است که در زبانهای دیگر با آن کار کرده و آشنایی دارید.
برای شروع کار ابتدا نیاز است تا همانند قسمتهای قبلی، کدهای صفحه مورد نظر خود را بنویسم و صفحه مورد نظر را ذخیره کنیم. کدها برای شروع کار، بدین شکل است که به صورت زیر نوشته و آماده شده است.
<html> <head> <meta charset="UTF-8"> <title>dotnet</title> </head> <body id="dotnettips"> <a v-on:click="message" href="bank.html">click here!</a> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.27/vue.min.js"> </script> <script type="text/javascript"> new Vue({ el: '#dotnettips', data:{ }, methods:{ message: function () { alert("hi friends"); } } }); </script> </body> </html>
در کدهای بالا قسمت body طبق روال همیشگی یک id را به خود اختصاص داده است و لازم است که بدانیم مشخصهی id درون بدنهی vue و مشخصهی el به کدام بخش تعلق گرفته است.
دقت بفرمائید که ما نیاز داریم تا یک function بنویسم و رویداد مورد نظر را اجرا کنیم که جهت آزمایش به دو صفحه html نیاز است و در بخش زیر از کدهای فوق قابل مشاهده است.
vue مورد نظر و متد برای اجرای رویداد بدین شکل نوشته شده است.
new Vue({ el: '#dotnettips', data:{ }, methods:{ message: function () { alert("hi friends"); } } });
<html> <head> <meta charset="UTF-8"> <title>dotnet</title> </head> <body id="dotnettips"> <a v-on:click="message" href="bank.html">click here!</a>
- حتما باید نام متد به رویداد کلیک معرفی شود که در کد فوق قابل مشاهده است.
نام صفحه مورد نظر برای ارجاع : bank.html
دقت شود، درون vue که نوشته شدهاست، یک متد نیز فراخوانی شده است تا رویداد، اجرا شود و ما نام آن متد را message در نظر گرفتهایم.
دو صفحه به دلخواه ساخته شدهاست که نام صفحه اول با نام cc.html و صفحه دوم با نام bank.html ایجاد شدهاند. زمان اجرای رویداد، به صفحه دوم و دریافت پیغام hi friends، توسط تابعی که نوشتهایم و نمایش آن بر روی صفحه مواجه خواهیم شد. بدین معنی است که رویداد به درستی اجرا شده است و سپس به صفحه دوم هدایت میشویم.
تصویری از خروجی ضمیمه شده است.
پیشنیازها:
چگونه با استفاده از لوسین مطالب را ایندکس کنیم؟
چگونه از افزونه jQuery Auto-Complete استفاده کنیم؟
نحوه استفاده صحیح از لوسین در ASP.NET
اگر به جستجوی سایت دقت کرده باشید، قابلیت ارائه پیشنهاداتی به کاربر توسط یک Auto-Complete به آن اضافه شدهاست. در مطلب جاری به بررسی این مورد به همراه دو مثال Web forms و MVC پرداخته خواهد شد.
قسمت عمده مطلب جاری با پیشنیازهای یاد شده فوق یکی است. در اینجا فقط به ذکر تفاوتها بسنده خواهد شد.
الف) دریافت لوسین
از طریق NuGet آخرین نگارش را دریافت و به پروژه خود اضافه کنید. همچنین Lucene.NET Contrib را نیز به همین نحو دریافت نمائید.
ب) ایجاد ایندکس
کدهای این قسمت با مطلب برجسته سازی قسمتهای جستجو شده، یکی است:
تنها تفاوت آن اضافه شدن titleField.Boost = 3 میباشد. توسط Boost به لوسین خواهیم گفت که اهمیت عبارات ذکر شده در عناوین مطالب، بیشتر است از اهمیت متون آنها.
ج) تهیه قسمت منبع داده Auto-Complete
توضیحات:
برای نمایش Auto-Complete نیاز به منبع داده داریم که نحوه ایجاد آنرا در کدهای فوق ملاحظه میکنید. در اینجا توسط جستجوی سریع لوسین و امکانات PrefixQuery آن، به تعدادی مشخص (maxItems)، رکوردهای یافت شده را بازگشت خواهیم داد. خروجی حاصل لیستی است از SearchResultها شامل عنوان مطلب و Id آن. عنوان را به کاربر نمایش خواهیم داد؛ از Id برای هدایت او به مطلبی مشخص استفاده خواهیم کرد.
د) نمایش Auto-Complete در ASP.NET MVC
توضیحات:
- ابتدا ارجاعاتی را به jQuery، افزونه Auto-Complete و اسکریپت سفارشی تهیه شده، در فایل layout پروژه تعریف خواهیم کرد.
در اینجا سه قسمت را مشاهده میکنید: کدهای کنترلر، View متناظر و اسکریپتی که Auto-Complete را فعال خواهد ساخت.
- قسمت مهم کدهای کنترلر، دو سطر زیر هستند:
مطابق نیاز افزونه انتخاب شده در مثال جاری، فرمت خروجی مدنظر باید شامل سطرهایی حاوی متن قابل نمایش به همراه یک Id (یا در اینجا یک آدرس مشخص) باشد. البته ذکر این Id اختیاری بوده و در اینجا جهت تکمیل بحث ارائه شده است.
return Content هم سبب بازگشت این اطلاعات به افزونه خواهد شد.
- کدهای View متناظر بسیار ساده هستند. تنها نام TextBox تعریف شده مهم میباشد که در متد جاوا اسکریپتی EnableSearchAutocomplete استفاده شده است. به علاوه، نحوه مقدار دهی آدرس دسترسی به اکشن متد ScoredTerms نیز مهم میباشد.
- در متد EnableSearchAutocomplete نحوه فراخوانی افزونه autocomplete را ملاحظه میکنید.
جهت آن، به راست به چپ تنظیم شده است. با 2 کاراکتر ورودی فعال خواهد شد با وقفهای کوتاه. نیازی نیست تا انتخاب کاربر از لیست ظاهر شده حتما با عبارت جستجو شده صد در صد یکی باشد. حداکثر 20 آیتم در لیست ظاهر خواهند شد. اسکرول بار لیست را حذف کردهایم. عرض آن به 300 تنظیم شده است و نحوه فرمت دهی نمایشی آنرا نیز ملاحظه میکنید. برای این منظور از متد formatItem استفاده شده است. آرایه row در اینجا در برگیرنده اعضای Title و Id ارسالی به افزونه است. اندیس صفر آن به عنوان دریافتی اشاره میکند.
همچنین نحوه نشان دادن عکس العمل به عنصر انتخابی را هم ملاحظه میکنید (در متد result مقدار دهی شده). window.location را به عنصر دوم آرایه row هدایت خواهیم کرد. این عنصر دوم مطابق کدهای اکشن متد تهیه شده، به آدرس یک صفحه اشاره میکند.
ه) نمایش Auto-Complete در ASP.NET WebForms
قسمت عمده مطالب فوق با وب فرمها نیز یکی است. خصوصا توضیحات مرتبط با متد EnableSearchAutocomplete ذکر شده.
در اینجا بجای Controller از یک Generic handler استفاده شده است (Search.ashx).
در آن، عنوان مطالب یافت شده به همراه یک آدرس مشخص، تهیه و در Response نوشته خواهند شد.
کدهای کامل مثال فوق را از اینجا میتوانید دریافت کنید:
همچنین باید دقت داشت که پروژه MVC آن از نوع MVC4 است (VS2010) و فرض براین میباشد که IIS Express 7.5 را نیز پیشتر نصب کردهاید.
کلمه عبور فایل: dotnettips91
چگونه با استفاده از لوسین مطالب را ایندکس کنیم؟
چگونه از افزونه jQuery Auto-Complete استفاده کنیم؟
نحوه استفاده صحیح از لوسین در ASP.NET
اگر به جستجوی سایت دقت کرده باشید، قابلیت ارائه پیشنهاداتی به کاربر توسط یک Auto-Complete به آن اضافه شدهاست. در مطلب جاری به بررسی این مورد به همراه دو مثال Web forms و MVC پرداخته خواهد شد.
قسمت عمده مطلب جاری با پیشنیازهای یاد شده فوق یکی است. در اینجا فقط به ذکر تفاوتها بسنده خواهد شد.
الف) دریافت لوسین
از طریق NuGet آخرین نگارش را دریافت و به پروژه خود اضافه کنید. همچنین Lucene.NET Contrib را نیز به همین نحو دریافت نمائید.
ب) ایجاد ایندکس
کدهای این قسمت با مطلب برجسته سازی قسمتهای جستجو شده، یکی است:
using System.Collections.Generic; using System.IO; using Lucene.Net.Analysis.Standard; using Lucene.Net.Documents; using Lucene.Net.Index; using Lucene.Net.Store; using LuceneSearch.Core.Model; using LuceneSearch.Core.Utils; namespace LuceneSearch.Core { public static class CreateIndex { static readonly Lucene.Net.Util.Version _version = Lucene.Net.Util.Version.LUCENE_30; public static Document MapPostToDocument(Post post) { var postDocument = new Document(); postDocument.Add(new Field("Id", post.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); var titleField = new Field("Title", post.Title, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS); titleField.Boost = 3; postDocument.Add(titleField); postDocument.Add(new Field("Body", post.Body.RemoveHtmlTags(), Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); return postDocument; } public static void CreateFullTextIndex(IEnumerable<Post> dataList, string path) { var directory = FSDirectory.Open(new DirectoryInfo(path)); var analyzer = new StandardAnalyzer(_version); using (var writer = new IndexWriter(directory, analyzer, create: true, mfl: IndexWriter.MaxFieldLength.UNLIMITED)) { foreach (var post in dataList) { writer.AddDocument(MapPostToDocument(post)); } writer.Optimize(); writer.Commit(); writer.Close(); directory.Close(); } } } }
ج) تهیه قسمت منبع داده Auto-Complete
namespace LuceneSearch.Core.Model { public class SearchResult { public int Id { set; get; } public string Title { set; get; } } }
using System.Collections.Generic; using System.IO; using Lucene.Net.Index; using Lucene.Net.Search; using Lucene.Net.Store; using LuceneSearch.Core.Model; using LuceneSearch.Core.Utils; namespace LuceneSearch.Core { public static class AutoComplete { private static IndexSearcher _searcher; /// <summary> /// Get terms starting with the given prefix /// </summary> /// <param name="prefix"></param> /// <param name="maxItems"></param> /// <returns></returns> public static IList<SearchResult> GetTermsScored(string indexPath, string prefix, int maxItems = 10) { if (_searcher == null) _searcher = new IndexSearcher(FSDirectory.Open(new DirectoryInfo(indexPath)), true); var resultsList = new List<SearchResult>(); if (string.IsNullOrWhiteSpace(prefix)) return resultsList; prefix = prefix.ApplyCorrectYeKe(); var results = _searcher.Search(new PrefixQuery(new Term("Title", prefix)), null, maxItems); if (results.TotalHits == 0) { results = _searcher.Search(new PrefixQuery(new Term("Body", prefix)), null, maxItems); } foreach (var doc in results.ScoreDocs) { resultsList.Add(new SearchResult { Title = _searcher.Doc(doc.Doc).Get("Title"), Id = int.Parse(_searcher.Doc(doc.Doc).Get("Id")) }); } return resultsList; } } }
برای نمایش Auto-Complete نیاز به منبع داده داریم که نحوه ایجاد آنرا در کدهای فوق ملاحظه میکنید. در اینجا توسط جستجوی سریع لوسین و امکانات PrefixQuery آن، به تعدادی مشخص (maxItems)، رکوردهای یافت شده را بازگشت خواهیم داد. خروجی حاصل لیستی است از SearchResultها شامل عنوان مطلب و Id آن. عنوان را به کاربر نمایش خواهیم داد؛ از Id برای هدایت او به مطلبی مشخص استفاده خواهیم کرد.
د) نمایش Auto-Complete در ASP.NET MVC
using System.Text; using System.Web.Mvc; using LuceneSearch.Core; using System.Web; namespace LuceneSearch.Controllers { public class HomeController : Controller { static string _indexPath = HttpRuntime.AppDomainAppPath + @"App_Data\idx"; public ActionResult Index(int? id) { if (id.HasValue) { //todo: do something } return View(); //Show the page } public virtual ActionResult ScoredTerms(string q) { if (string.IsNullOrWhiteSpace(q)) return Content(string.Empty); var result = new StringBuilder(); var items = AutoComplete.GetTermsScored(_indexPath, q); foreach (var item in items) { var postUrl = this.Url.Action(actionName: "Index", controllerName: "Home", routeValues: new { id = item.Id }, protocol: "http"); result.AppendLine(item.Title + "|" + postUrl); } return Content(result.ToString()); } } }
@{ ViewBag.Title = "جستجو"; var scoredTermsUrl = Url.Action(actionName: "ScoredTerms", controllerName: "Home"); var bulletImage = Url.Content("~/Content/Images/bullet_shape.png"); } <h2> جستجو</h2> <div align="center"> @Html.TextBox("term", "", htmlAttributes: new { dir = "ltr" }) <br /> جهت آزمایش lu را وارد نمائید </div> @section scripts { <script type="text/javascript"> EnableSearchAutocomplete('@scoredTermsUrl', '@bulletImage'); </script> }
function EnableSearchAutocomplete(url, img) { var formatItem = function (row) { if (!row) return ""; return "<img src='" + img + "' /> " + row[0]; } $(document).ready(function () { $("#term").autocomplete(url, { dir: 'rtl', minChars: 2, delay: 5, mustMatch: false, max: 20, autoFill: false, matchContains: false, scroll: false, width: 300, formatItem: formatItem }).result(function (evt, row, formatted) { if (!row) return; window.location = row[1]; }); }); }
- ابتدا ارجاعاتی را به jQuery، افزونه Auto-Complete و اسکریپت سفارشی تهیه شده، در فایل layout پروژه تعریف خواهیم کرد.
در اینجا سه قسمت را مشاهده میکنید: کدهای کنترلر، View متناظر و اسکریپتی که Auto-Complete را فعال خواهد ساخت.
- قسمت مهم کدهای کنترلر، دو سطر زیر هستند:
result.AppendLine(item.Title + "|" + postUrl); return Content(result.ToString());
return Content هم سبب بازگشت این اطلاعات به افزونه خواهد شد.
- کدهای View متناظر بسیار ساده هستند. تنها نام TextBox تعریف شده مهم میباشد که در متد جاوا اسکریپتی EnableSearchAutocomplete استفاده شده است. به علاوه، نحوه مقدار دهی آدرس دسترسی به اکشن متد ScoredTerms نیز مهم میباشد.
- در متد EnableSearchAutocomplete نحوه فراخوانی افزونه autocomplete را ملاحظه میکنید.
جهت آن، به راست به چپ تنظیم شده است. با 2 کاراکتر ورودی فعال خواهد شد با وقفهای کوتاه. نیازی نیست تا انتخاب کاربر از لیست ظاهر شده حتما با عبارت جستجو شده صد در صد یکی باشد. حداکثر 20 آیتم در لیست ظاهر خواهند شد. اسکرول بار لیست را حذف کردهایم. عرض آن به 300 تنظیم شده است و نحوه فرمت دهی نمایشی آنرا نیز ملاحظه میکنید. برای این منظور از متد formatItem استفاده شده است. آرایه row در اینجا در برگیرنده اعضای Title و Id ارسالی به افزونه است. اندیس صفر آن به عنوان دریافتی اشاره میکند.
همچنین نحوه نشان دادن عکس العمل به عنصر انتخابی را هم ملاحظه میکنید (در متد result مقدار دهی شده). window.location را به عنصر دوم آرایه row هدایت خواهیم کرد. این عنصر دوم مطابق کدهای اکشن متد تهیه شده، به آدرس یک صفحه اشاره میکند.
ه) نمایش Auto-Complete در ASP.NET WebForms
قسمت عمده مطالب فوق با وب فرمها نیز یکی است. خصوصا توضیحات مرتبط با متد EnableSearchAutocomplete ذکر شده.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="LuceneSearch.WebForms.Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>جستجو</title> <link href="Content/Site.css" rel="stylesheet" type="text/css" /> <script src="Scripts/jquery-1.7.1.min.js" type="text/javascript"></script> <script src="Scripts/jquery.autocomplete.js" type="text/javascript"></script> <script src="Scripts/custom.js" type="text/javascript"></script> </head> <body dir="rtl"> <h2> جستجو</h2> <form id="form1" runat="server"> <div align="center"> <asp:TextBox runat="server" dir="ltr" ID="term"></asp:TextBox> <br /> جهت آزمایش lu را وارد نمائید </div> </form> <script type="text/javascript"> EnableSearchAutocomplete('Search.ashx', 'Content/Images/bullet_shape.png'); </script> </body> </html>
using System.Text; using System.Web; using LuceneSearch.Core; namespace LuceneSearch.WebForms { public class Search : IHttpHandler { static string _indexPath = HttpRuntime.AppDomainAppPath + @"App_Data\idx"; public void ProcessRequest(HttpContext context) { string q = context.Request.QueryString["q"]; if (string.IsNullOrWhiteSpace(q)) { context.Response.Write(string.Empty); context.Response.End(); } var result = new StringBuilder(); var items = AutoComplete.GetTermsScored(_indexPath, q); foreach (var item in items) { var postUrl = "Default.aspx?id=" + item.Id; result.AppendLine(item.Title + "|" + postUrl); } context.Response.ContentType = "text/plain"; context.Response.Write(result.ToString()); context.Response.End(); } public bool IsReusable { get { return false; } } } }
در اینجا بجای Controller از یک Generic handler استفاده شده است (Search.ashx).
result.AppendLine(item.Title + "|" + postUrl); context.Response.Write(result.ToString());
کدهای کامل مثال فوق را از اینجا میتوانید دریافت کنید:
همچنین باید دقت داشت که پروژه MVC آن از نوع MVC4 است (VS2010) و فرض براین میباشد که IIS Express 7.5 را نیز پیشتر نصب کردهاید.
کلمه عبور فایل: dotnettips91
مطالب دورهها
عیب یابی و دیباگ برنامههای SignalR
1) برنامه SignalR در IE کار نمیکند.
پردازشگر json، در نگارشهای اخیر IE به آن اضافه شده است. برای رفع این مشکل در نگارشهای قدیمی، نیاز است از اسکریپت کمکی http://nuget.org/List/Packages/json2 استفاده نمائید. همچنین مرورگر IE را نیز باید وادار ساخت تا بر اساس آخرین موتور پردازشی خود کار کند:
2) هنگام فراخوانی مسیر signalr/hubs پیغام 404 (یافت نشد) دریافت میشود.
برای رفع این مشکل ابتدا اطمینان حاصل کنید که تنظیمات مسیریابی تعریف شده در فایل global.asax.cs موجود هستند.
در ادامه اطمینان حاصل نمائید مسیر اسکریپتهای signalr/hubs به درستی تعریف شدهاند:
برای مثال در برنامههای MVC و وب فرمها تعریف صحیح باید به شکل زیر باشد:
همچنین وجود تنظیمات ذیل را در فایل وب کانفیگ برنامه نیز بررسی کنید:
3) متدهای سمت کلاینت من فراخوانی نمیشوند.
بهترین راه برای مشاهده ریز جرئیات خطاها، ذکر سطر ذیل در کدهای سمت کلاینت جاوا اسکریپتی برنامه است:
و سپس مراجعه به کنسول جاوا اسکریپت مرورگر برای بررسی خطاهای لاگ شده.
4) خطای «Connection must be started before data can be sent» را دریافت میکنم.
همانطور که در قسمت قبل عنوان شد، کلیه فراخوانیهای SignalR از نوع غیرهمزمان هستند. بنابراین باید با استفاده از callback و زمان فراخوانی آنها که عموما پس از برقراری اتصال رخ میدهد، نسبت به انجام امور دلخواه اقدام کرد.
همانطور که در این مثال مشاهده میکنید، سطر proxy.invoke در یک callback فراخوانی شده است و نه بلافاصله در سطری پس از connection.start. هر زمان که اتصال به نحو موفقیت آمیزی برقرار شد، آنگاه متد subscribe در سمت سرور فراخوانی میگردد.
در حالت استفاده بدون پروکسی نیز چنین callbackهایی قابل تعریف هستند:
5) بعد از 10 اتصال به IIS، برنامه متوقف میشود.
این مورد، محدودیت ذاتی IIS 7 نصب شده بر روی ویندوز 7 است. بهتر است از یک IIS کامل موجود در ویندوزهای سرور استفاده کنید. در این سرورها عدد پیش فرض تنظیم شده 5000 اتصال است که در صورت نیاز با استفاده از دستور زیر قابل تغییر است:
به علاوه ASP.NET نیز محدودیت 5000 اتصال به ازای هر CPU را دارد. برای تغییر آن باید به مسیر ذیل مراجعه
و سپس مقدار maxConcurrentRequestsPerCPU را تنظیم کرد:
به علاوه ASP.NET پس از رد شدن از حد maxConcurrentRequestsPerCPU، درخواستها را در صف قرار میدهد. این مورد نیز قابل تنظیم است. ابتدا به مسیر ذیل مراجعه کرده
و سپس در صورت نیاز و لزوم، مقدار requestQueueLimit را تغییر دهید:
پردازشگر json، در نگارشهای اخیر IE به آن اضافه شده است. برای رفع این مشکل در نگارشهای قدیمی، نیاز است از اسکریپت کمکی http://nuget.org/List/Packages/json2 استفاده نمائید. همچنین مرورگر IE را نیز باید وادار ساخت تا بر اساس آخرین موتور پردازشی خود کار کند:
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
2) هنگام فراخوانی مسیر signalr/hubs پیغام 404 (یافت نشد) دریافت میشود.
برای رفع این مشکل ابتدا اطمینان حاصل کنید که تنظیمات مسیریابی تعریف شده در فایل global.asax.cs موجود هستند.
در ادامه اطمینان حاصل نمائید مسیر اسکریپتهای signalr/hubs به درستی تعریف شدهاند:
<script type="text/javascript" src="/signalr/hubs"></script>
MVC: <script type="text/javascript" src="@Url.Content("~/signalr/hubs")"></script> Web forms: <script type="text/javascript" src='<%= ResolveClientUrl("~/signalr/hubs") %>'></script>
<configuration> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> </modules> </system.webServer> </configuration>
3) متدهای سمت کلاینت من فراخوانی نمیشوند.
بهترین راه برای مشاهده ریز جرئیات خطاها، ذکر سطر ذیل در کدهای سمت کلاینت جاوا اسکریپتی برنامه است:
$.connection.hub.logging = true;
4) خطای «Connection must be started before data can be sent» را دریافت میکنم.
همانطور که در قسمت قبل عنوان شد، کلیه فراخوانیهای SignalR از نوع غیرهمزمان هستند. بنابراین باید با استفاده از callback و زمان فراخوانی آنها که عموما پس از برقراری اتصال رخ میدهد، نسبت به انجام امور دلخواه اقدام کرد.
var connection = $.hubConnection('http://localhost:8081/'); proxy = connection.createProxy('collectionhub') connection.start() .done(function () { proxy.invoke('subscribe', 'Product'); $('#messages').append('<li>invoked subscribe</li>'); }) .fail(function () { alert("Could not Connect!"); });
در حالت استفاده بدون پروکسی نیز چنین callbackهایی قابل تعریف هستند:
$.connection.hub.start() .done(function() { myHub.server.SomeFunction(SomeParam) //e.g. a login or init .done(connectionReady); }) .fail(function() { alert("Could not Connect!"); });
5) بعد از 10 اتصال به IIS، برنامه متوقف میشود.
این مورد، محدودیت ذاتی IIS 7 نصب شده بر روی ویندوز 7 است. بهتر است از یک IIS کامل موجود در ویندوزهای سرور استفاده کنید. در این سرورها عدد پیش فرض تنظیم شده 5000 اتصال است که در صورت نیاز با استفاده از دستور زیر قابل تغییر است:
appcmd.exe set config /section:system.webserver/serverRuntime /appConcurrentRequestLimit:100000
%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet.config
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <runtime> <legacyUnhandledExceptionPolicy enabled="false" /> <legacyImpersonationPolicy enabled="true"/> <alwaysFlowImpersonationPolicy enabled="false"/> <SymbolReadingPolicy enabled="1" /> <shadowCopyVerifyByTimestamp enabled="true"/> </runtime> <startup useLegacyV2RuntimeActivationPolicy="true" /> <system.web> <applicationPool maxConcurrentRequestsPerCPU="20000" /> </system.web> </configuration>
%windir%\Microsoft.NET\Framework\v4.0.30319\Config\machine.config
<processModel autoConfig="false" requestQueueLimit="250000" />
مدتی قبل سؤال مهمی در سایت مطرح شد، به شرح زیر:
«من از کنترلهای تلریک استفاده میکنم که یک سری اسکریپت را بصورت
http://localhost:1244/WebResource.axd?d=aklE6L8AEfPEgIS3T-oXc6mevPfbpi6VRp_ZTP2nBVrnt5ULOFYD3GNWRrDHwANC3VDQlL8dLAa5g35dzgHyuzAgAguIpYrf-_NXIJwNNu0YRSnH3-MgKMfnwKBKF_Lk2E5oeIcLL78uDlQ0se_GxQ2&t=635231470568640000
به فرم تزریق میکند و بعضی وقتها داخلش xp و یا یک سری دستورات اسکیوال تولید میشوند. در این حالت این مسیرها توسط ISA Server در شبکه داخلی حمله تشخیص داده شده و بلاک خواهند شد و عملا برنامه از کار میافتد. آیا راهی برای خلاصی از دست آنها هست؟»
پاسخ: بلی. از دات نت 3 و نیم به بعد، امکان جایگزینی کامل اسکریپتهای خودکار مدفون شده در اسمبلیها با فایلهای استاتیک پیش بینی شدهاست که در ادامه نحوهی استخراج و کار با آنها را بررسی خواهیم کرد.
الف) یافتن اسکریپتهای مدفون در اسمبلیها
در ابتدا اسمبلی حاوی کنترلهای وب فرم مدنظر خود را باید توسط برنامههای Reflector یا ILSpy و امثال آنها گشوده و نام دقیق منبع و همچنین محتوای آن فایل اسکریپت را استخراج کنید. برای مثال:
در این تصویر، اسمبلی استاندارد System.Web.Extensions مورد بررسی قرار گرفته است. برای نمونه اگر بخواهید اسکریپتهای متناظر با ScriptManager و UpdatePanel را با معادلهای استاتیک آنها جایگزین کنید، باید دو فایل MicrosoftAjaxWebForms.js و MicrosoftAjax.js را از این اسمبلی استخراج نمائید. (برنامههای یاد شده امکان ذخیره سازی منابع را نیز میدهند)
ب) وادار کردن ASP.NET به استفاده از نسخهی استاتیک منابع
فرض کنید دو اسکریپت یاد شده را در فایلهای staticJS1.js و staticJS2.js در ریشهی سایت خود ذخیره کردهاید. اکنون یک ScriptManager را به صفحه اضافه کرده و مطابق کدهای فوق، اسکریپتهای مدفون شده در اسمبلی System.Web.Extensions را به این فایلهای استاتیک هدایت کنید. همانطور که عنوان شد نام این مداخل باید دقیقا با نام موجود در اسمبلی یکی باشد؛ در غیر اینصورت با خطای ذیل مواجه خواهید شد:
اکنون اگر برنامه را اجرا کنید (با فرض قرار داشتن یک ScriptManager و UpdatePanel در صفحه)، اینبار دیگر در سورس صفحه، شاهد آدرسهای طولانی WebResource.axd و ScriptResource.axd نخواهید بود. به صورت خودکار از دو فایل استاتیک تنظیم شده، استفاده میشود:
بدیهی است در صورت نیاز، باید تعاریف سایر اسکریپتهای مدفون در اسمبلی یاد شده یا اسمبلی System.Web را نیز به صفحه از طریق ScriptManager اضافه کرد. در مورد کنترلهای ثالث نیز وضع به همین صورت است و استاندارد آن تفاوتی نمیکند.
یک نکتهی تکمیلی
در مطلب «ASP.NET 4.5 ScriptManager Improvements in WebForms » مشاهده خواهید کرد که از ASP.NET 4.5 به بعد، طی دو بستهی نیوگت که هر از چندگاهی به روز میشوند، کلیه اسکریپتهای System.Web و System.Web.Extensions خارج از این اسمبلیها نیز قابل دریافت بوده و با استفاده از سیستم bunding & minification میتوان آنها را فشرده و یکی کرد.
«من از کنترلهای تلریک استفاده میکنم که یک سری اسکریپت را بصورت
http://localhost:1244/WebResource.axd?d=aklE6L8AEfPEgIS3T-oXc6mevPfbpi6VRp_ZTP2nBVrnt5ULOFYD3GNWRrDHwANC3VDQlL8dLAa5g35dzgHyuzAgAguIpYrf-_NXIJwNNu0YRSnH3-MgKMfnwKBKF_Lk2E5oeIcLL78uDlQ0se_GxQ2&t=635231470568640000
به فرم تزریق میکند و بعضی وقتها داخلش xp و یا یک سری دستورات اسکیوال تولید میشوند. در این حالت این مسیرها توسط ISA Server در شبکه داخلی حمله تشخیص داده شده و بلاک خواهند شد و عملا برنامه از کار میافتد. آیا راهی برای خلاصی از دست آنها هست؟»
پاسخ: بلی. از دات نت 3 و نیم به بعد، امکان جایگزینی کامل اسکریپتهای خودکار مدفون شده در اسمبلیها با فایلهای استاتیک پیش بینی شدهاست که در ادامه نحوهی استخراج و کار با آنها را بررسی خواهیم کرد.
الف) یافتن اسکریپتهای مدفون در اسمبلیها
در ابتدا اسمبلی حاوی کنترلهای وب فرم مدنظر خود را باید توسط برنامههای Reflector یا ILSpy و امثال آنها گشوده و نام دقیق منبع و همچنین محتوای آن فایل اسکریپت را استخراج کنید. برای مثال:
در این تصویر، اسمبلی استاندارد System.Web.Extensions مورد بررسی قرار گرفته است. برای نمونه اگر بخواهید اسکریپتهای متناظر با ScriptManager و UpdatePanel را با معادلهای استاتیک آنها جایگزین کنید، باید دو فایل MicrosoftAjaxWebForms.js و MicrosoftAjax.js را از این اسمبلی استخراج نمائید. (برنامههای یاد شده امکان ذخیره سازی منابع را نیز میدهند)
ب) وادار کردن ASP.NET به استفاده از نسخهی استاتیک منابع
<asp:ScriptManager ID="Scriptmanager1" runat="server"> <Scripts> <asp:ScriptReference Name="MicrosoftAjaxWebForms.js" Assembly="System.Web.Extensions" Path="~/staticJS1.js" /> <asp:ScriptReference Name="MicrosoftAjax.js" Assembly="System.Web.Extensions" Path="~/staticJS2.js" /> </Scripts> </asp:ScriptManager>
The assembly 'System.Web.Extensions' does not contain a Web resource that has the name 'xyz.js'. Make sure that the resource name is spelled correctly. Make sure that the application references the correct version of an ASP.NET AJAX Framework assembly.
<script src="staticJS1.js" type="text/javascript"></script> <script src="staticJS2.js" type="text/javascript"></script>
یک نکتهی تکمیلی
در مطلب «ASP.NET 4.5 ScriptManager Improvements in WebForms » مشاهده خواهید کرد که از ASP.NET 4.5 به بعد، طی دو بستهی نیوگت که هر از چندگاهی به روز میشوند، کلیه اسکریپتهای System.Web و System.Web.Extensions خارج از این اسمبلیها نیز قابل دریافت بوده و با استفاده از سیستم bunding & minification میتوان آنها را فشرده و یکی کرد.
On 28 of May, 2014, the first commit of Immutable.js was pushed in the facebook’s organization on GitHub. Immutable.js is a set of immutable data structures (List, Set, Map, etc.) implemented in JavaScript.
Plain JavaScript array
20 | 10 | 5 | 1 | تعداد watch - تعداد آرایه |
2.58 | 2.573 | 2.56 | 2.517 | 100 |
2.853 | 2.747 | 2.675 | 2.555 | 1000 |
15.68 | 7.736 | 4.025 | 2.861 | 10000 |
Immutable JavaScript list
20 | 10 | 5 | 1 | تعداد watch - تعداد آرایه |
2.569 | 2.562 | 2.507 | 2.696 | 100 |
2.49 | 2.569 | 2.54 | 2.715 | 1000 |
2.708 | 2.599 | 2.538 | 2.832 | 10000 |
یک نکتهی تکمیلی: امکان بالابردن سرعت بارگذاری برنامههای مبتنی بر EF 6.2 به صورت توکار
با به روز رسانی ارجاعات EF مورد استفاده:
تنها کافی است قطعه کد ذیل را به اسمبلی حاوی Context خود اضافه کنید:
تشخیص و استفادهی از آن توسط EF 6.2 خودکار است. پس از آن یک کش محلی، از مدل سیستم تهیه میشود (Entity Framework Code First Model Cache) و در مسیری که قید شده (پارامتر DefaultDbModelStore)، ذخیره خواهد شد؛ مانند:
بازسازی این کش محلی بجای تولید پویای آن در هربار بارگذاری برنامه (که سرعت آغاز برنامه را کاهش میدهد)، بر اساس مقایسهی تاریخ آخرین تغییر اسمبلی حاوی Context برنامه با تاریخ آخرین تغییر فایل کش محلی است. اگر این دو یکی نبودند، این کش بازتولید خواهد شد.
پس از این تغییر کوچک، اولین بار اجرای برنامه همانند حالت تولید پویای Entity Framework Code First Model Cache که پیشتر در حافظه انجام میشد، اندکی طول کشیده و نتیجهی آن در فایل edmx یاد شده ذخیره میشود. از بار دوم اجرای برنامه، Model Cache از فایل edmx محلی خوانده شده و به این ترتیب سرعت آغاز برنامه به شدت افزایش خواهد یافت.
برای نمونه عنوان شدهاست که با استفاده از این روش، سرعت بارگذاری Context ایی با 600 مدل، از 14 ثانیه به 2 ثانیه کاهش یافتهاست.
یک نکته: برای برنامههای وب بهتر است از مسیر پوشهی محافظت شدهی App_Data به عنوان پارامتر DefaultDbModelStore استفاده کنید:
با به روز رسانی ارجاعات EF مورد استفاده:
To Update PM> Update-Package EntityFramework -Version 6.2.0 To install PM> Install-Package EntityFramework -Version 6.2.0
public class MyDbConfiguration : DbConfiguration { public MyDbConfiguration() : base() { SetModelStore(new DefaultDbModelStore(Directory.GetCurrentDirectory())); } }
/bin/Debug/MyAssembly.MyNamespace.MyDbContext.edmx
پس از این تغییر کوچک، اولین بار اجرای برنامه همانند حالت تولید پویای Entity Framework Code First Model Cache که پیشتر در حافظه انجام میشد، اندکی طول کشیده و نتیجهی آن در فایل edmx یاد شده ذخیره میشود. از بار دوم اجرای برنامه، Model Cache از فایل edmx محلی خوانده شده و به این ترتیب سرعت آغاز برنامه به شدت افزایش خواهد یافت.
برای نمونه عنوان شدهاست که با استفاده از این روش، سرعت بارگذاری Context ایی با 600 مدل، از 14 ثانیه به 2 ثانیه کاهش یافتهاست.
یک نکته: برای برنامههای وب بهتر است از مسیر پوشهی محافظت شدهی App_Data به عنوان پارامتر DefaultDbModelStore استفاده کنید:
var appDataDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data"); //OR var appDataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();
همانطور که در دوره SignalR سایت نیز مطرح شدهاست : "یکی از کاربردهای جالب SignalR میتواند به روز رسانی مداوم صفحه نمایش کاربران، توسط اطلاعات ارسالی از طرف سرور باشد." در ادامه میخواهیم به طراحی یک "تخته وایت برد" آنلاین بپردازیم.
در این پروژه برای ترسم خطوط بر روی صفحه از Canvas در HTML5 استفاده میشود.
پیشنیازها :
تعریف کلاس Hub برنامه :
کدهای کلاینتهای متصل به هاب در فایل Whiteboard.js :
کدهای کامل سمت کلاینت :
در ابتدا یک دکمه برای تغییر رنگ قلم و یک لیست بازشو برای تعیین اندازهی قلم و همچنین یک دکمه برای پاک کردن صفحه نمایش قرار داده شده است. سپس یک Canvas به نام draw ایجاد کرده ایم که بتوانیم خطوط خود را بر روی آن رسم کنیم.
پیشنیازهای این مطلب با مطلب «مثال - نمایش درصد پیشرفت عملیات توسط SignalR» یکی است. برای مثال، نحوه دریافت وابستگیها، تنظیمات فایل global.asax و افزودن اسکریپتها، تفاوتی با مقالهی ذکر شده ندارد و تنها تعدادی اسکریپت و CSS جهت زیبایی کار افزوده شده است :
<link href="Styles/bootstrap.min.css" rel="stylesheet" /> //برای نمایش و استفاده از جعبهی رنگ در بوت استراپ <link href="Styles/bootstrap-colorpalette.css" rel="stylesheet" /> <script src="Scripts/jquery-1.8.2.js"></script> <script type="text/javascript" src='Scripts/jquery.signalR-1.1.3.js'></script> <script src="Scripts/bootstrap.min.js"></script> <script src="Scripts/bootstrap-colorpalette.js"></script> <script type="text/javascript" src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script> //حاوی متدهایی برای رسم خط با استفاده از HTML5 <script src="Scripts/draw.js" type="text/javascript"></script> //تعریف کلاینتهای متصل به هاب <script src="Scripts/Whiteboard.js"></script>
تعریف کلاس Hub برنامه :
using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; using OnlineSignalRWhiteboard.Model; namespace OnlineSignalRWhiteboard.Hubs { [HubName("onWhiteboard")] public class Whiteboard : Hub { public void OnDrawPen(Point prev, Point current, string color, int width) { Clients.All.drawPen(prev, current, color, width); } public void ClearBoard() { Clients.All.clear(); } } }
در ابتدا توسط ویژگی HubName یک نام مشخص برای هاب خود انتخاب کرده ایم. سپس متدی به نام OnDrawPen تعریف شده است که پس از فراخوانی از سمت کلاینت، مقادیر دریافتی خود را با صدا زدن متدی در سمت کلاینت به نام drawPen ، به تمام کلاینتها ارسال و نقاط مربوطه در سمت کلاینت، بر روی صفحه رسم میشوند.
متد دیگری به نام ClearBoard نیز تعریف شده است که روال رخدادگردان clear در سمت کلاینت را فراخوانی میکند و باعث پاک شدن صفحه نمایش میشود.
کدهای کلاینتهای متصل به هاب در فایل Whiteboard.js :
$(function () { $.connection.hub.logging = true; var whiteboard = $.connection.onWhiteboard; $("#clear").click(function () { //پاک کردن صفحه نمایش whiteboard.server.clearBoard(); }); var color = function (colors) { //تغییر رنگ قلم draw.colour = colors; }; $(".size").click(function () { //تغییر سایز قلم draw.lineWidth = $(this).height(); $('#size').css('height', $(this).height()); }); $.connection.hub.start().done(function () { }) .fail(function () { alert("Could not Connect!"); }); draw.onDraw = function (prev, current, color, width) { //ارسال پارامترها به سمت سرور تا سرور بتواند دادهها را به سمت سایر کلاینتها نیز ارسال کند whiteboard.server.onDrawPen(prev, current, color, width); }; whiteboard.client.drawPen = function (prev, current, color, width) { draw.drawPen(prev, current, color, width); }; whiteboard.client.clear = function () { draw.clear(); }; $('#colorpalette3').colorPalette() .on('selectColor', function (e) { $('#color').css('background-color', e.color); color(e.color); }); var canvas = document.getElementById('draw'); //تغییر سایر کانواس متناسب با پنجرهی مرورگر window.addEventListener('resize', resizeCanvas, false); function resizeCanvas() { canvas.width = window.innerWidth - 20; canvas.height = window.innerHeight - 70; } resizeCanvas(); });
در این قطعه کد ابتدا ارجاعی به هاب مشخص شده است و سپس روالهای رخداد گردانی مانند whiteboard.client.drawPen و whiteboard.client.clear تعریف شده اند که به ترتیب متصل هستند به فراخوانی های Clients.All.drawPen و Clients.All.clear در سمت سرور.
همچنین یک متد به نام draw.onDraw تعریف شده است که وظیفهی آن ارسال اطاعاتی نظیر موقعیت موس در صفحه، رنگ، اندازه و ... به سمت متدی به نام onDrawPen در هاب است.
کدهای کامل سمت کلاینت :
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <link href="Styles/bootstrap.min.css" rel="stylesheet" /> <link href="Styles/bootstrap-colorpalette.css" rel="stylesheet" /> <script src="Scripts/jquery-1.8.2.js"></script> <script type="text/javascript" src='Scripts/jquery.signalR-1.1.3.js'></script> <script src="Scripts/bootstrap.min.js"></script> <script src="Scripts/bootstrap-colorpalette.js"></script> <script type="text/javascript" src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script> <script src="Scripts/draw.js" type="text/javascript"></script> <script src="Scripts/Whiteboard.js"></script> </head> <body> <form id="form1" runat="server"> <div> <div style="position: static;"> <div> <div> <a data-toggle="collapse" data-target=".navbar-inverse-collapse"> <span></span> <span></span> <span></span> </a> <a href="#">تخته وایت برد آنلاین توسط SignalR و HTML5</a> <div> <ul> <li> <div> <a id="selected-color2" data-toggle="dropdown"> <div style="width: 20px; height: 20px; background: black" id="color"> </div> </a> <ul style="width:293px;"> <li style="display:inline-block;"> <div>رنگ پس زمینه</div> <div id="colorpalette3"></div> </li> </ul> </div> </li> <li></li> <li> <div> <a data-toggle="dropdown" style="width: 120px; height: 20px" href="#"> <hr style="width: 120px; height: 1px; background-color: black;margin: 0px; display: table-cell" id="size"> </a> <ul style="width: 120px"> <li><hr style="width: 140px; height: 1px; background-color: black"></li> <li></li> <li><hr style="width: 140px; height: 3px; background-color: black"></li> <li></li> <li><hr style="width: 140px; height: 7px; background-color: black"></li> <li></li> <li><hr style="width: 140px; height: 10px; background-color: black"></li> <li></li> <li><hr style="width: 140px; height: 20px; background-color: black"></li> </ul> </div> </li> <li></li> <li> <div> <a href="#" id="clear"><i></i>جدید</a> </div> </li> </ul> </div><!-- /.nav-collapse --> </div> </div><!-- /navbar-inner --> </div> </div> <div> <div> <canvas id="draw" style="cursor: crosshair;border: 1px solid black;"></canvas> </div> </div> </form> </body> </html>
کدهای کامل این مثال را میتوانید از اینجا دانلود کنید : OnlineSignalRWhiteboard.zip
و همچنین میتوانید نمونهی بهینه شدهی آن را نیز از این قسمت دانلود کنید : OnlineCustomSignalRWhiteboard.zip
در این سری از مقالات آموزش FireBug ، به صورت ترتیبی پیش رفتیم و ابتدا توضیحات تقریبا مفصلی در مورد پنل Console دادیم.
این پنل به سه بخش اصلی تقسیم میشود :
در این مقاله با دو بخش NodeView و Panel Toolbar ، و در مقالهی بعد با پنلهای سمت راست یعنی Side Panels آشنا میشویم.
ویرایش HTML
برای اضافه کردن یک Attribute جدید به تگ هم بروی تگ مورد نظر راست کلیک میکنید و سپس گزینهی New Attribute را انتخاب میکنید. ابتدا نام ویژگی ، یک Enter ، سپس مقدار را وارد میکنید. با زدن کلیدهای Enter متوالی ، میتوانید به وارد کردن ویژگیها ادامه دهید.
Options Menu
Context Menu
اکنون به پرکاربردترین بخش آن ، یعنی پنل HTML میرسیم.
محتویاتی که در این پنل نمایش داده میشود ، کدهای صفحهی جاری ، بصورت زنده است و با چیزی که از سمت سرور به مرورگر ارسال میشود متفاوت است ، تگهای HTML بصورت درختی مرتب شده اند و رنگی نمایش داده میشوند و امکان ویرایش محتوا ، ویرایش استایل ، مشاهدهی آرایش تگها بصورت بصری و ... وجود دارد.
نگاهی به کدهای ارسال شده به مرورگر در آدرس Google.com و نحوهی نمایش آن در فایرباگ را ملاحظه بفرمایید.
( کدهای ارسال شده سمت چپ - نمایش در فایرباگ سمت راست )
این پنل به سه بخش اصلی تقسیم میشود :
- بخش اصلی یا NodeView که محتوای صفحه را بصورت درختی و مرتب و رنگی نمایش میدهد.
- Panel Toolbar که در بالای پنل قرار دارد.
- Side Panels که شامل پنلهای Style , Computed , Layout , DOM میشود.
که به ترتیب برای نمایش و ویرایش استایلها ، مشاهده استایلهای محاسبه شده ، مشاهده Layout یا آرایش و نمایش اطلاعات DOM تگ انتخاب شده در NodeView است.
در این مقاله با دو بخش NodeView و Panel Toolbar ، و در مقالهی بعد با پنلهای سمت راست یعنی Side Panels آشنا میشویم.
ویرایش HTML
هر تگ HTML از یک سری Attribute تشکیل میشود که در فایرباگ نام ویژگی بصورت آبی تیره و مقدار آن با رنگ قرمز مشخص شده است. برای ویرایش هریک از آنها کافیست برویش کلیک کنید تا آن مقدار در یک باکس ویرایش به نمایش دربیاید.
با ویرایش مقدار ، این تغییر در لحظه بروی صفحه اعمال میشود.
برای اضافه کردن یک Attribute جدید به تگ هم بروی تگ مورد نظر راست کلیک میکنید و سپس گزینهی New Attribute را انتخاب میکنید. ابتدا نام ویژگی ، یک Enter ، سپس مقدار را وارد میکنید. با زدن کلیدهای Enter متوالی ، میتوانید به وارد کردن ویژگیها ادامه دهید.
برای ویرایش کردن یک تگ و تگهای فرزندش ، بروی تگ موردنظر کلیک کنید تا به حالت انتخاب دربیاید ، سپس بروی دکمهی Edit در بالای پنل کلیک کنید. در نهایت بعد از انجام ویرایش ، مجددا بروی دکمهی Edit کلیک کنید.
Node View
NodeView نام بخش اصلی پنل HTML است که محتویات صفحه را بصورت مرتب شده و درختی نمایش میدهد.
تگ (Node) هایی که دارای فرزند میباشند ، یک علامت + یا - در کنارشان وجود دارد که با کلیک بروی آن میتوانید آن تگ را باز/بسته کنید. همچنین این کار با کلیدهای + و - یا Right Arrow و Left Arrow از روی کیبورد هم قابل انجام است.
برای باز کردن یک لینک در این قسمت هم از ترکیب Ctrl و کلیک موس کمک بگیرید.
در نهایت زمانی که موس را بروی یک تگ قرار میدهید ، محیطی که توسط آن تگ در صفحه اشغال شده است بصورت رنگی مشخص میشود.
که رنگ زرد به معنی محیط margin ، رنگ آبی تیره به معنی محیط padding و رنگ آبی روشن هم به معنی محیط محتوا است.
Panel Toolbar
این قسمت در بالای پنل HTML قرار دارد که گزینههای زیر را دارا میباشد:
- Break On Mutate
این دکمه امکان توقف کد JavaScript ای که سعی در ویرایش محتوای صفحه را دارد ، میدهد.
زمانی که FireBug تشخیص دهد که کدی سعی در ویرایش محتوا دارد ، شما را به خط مورد نظر از کد ، در پنل Script منتقل میکند.
- Edit
این دکمه برای ویرایش مستقیم محتوای یک تگ بکار میرود
نکتهی جالب در ویرایش محتوا در فایرباگ این است که تغییرات در لحظه اعمال میشوند و نیاز به عمل بروزرسانیِ جداگانه نیست. برای مثال در همین قسمت Edit ، با هر ویرایش محتوا ، تغییرات در لحظه اعمال میشوند.
- Element Path
زمانی که یک تگ را در FireBug انتخاب میکنید ، لیستی از تگها که از تگ جاری شروع و به تگ ریشه ختم میشود ، نمایش داده میشود که با کلیک بروی هرکدام ، همان به عنوان تگ فعلی یا انتخاب شده تعیین میشود.
نتیجهی عملیاتی که بروی این تگهای انجام میدهید (حرکت موس و راست کلیک کردن) معادل همان عملیات بروی تگهای نمایش داده شده در قسمت اصلی (NodeView) است.
Options Menu
هر تب یا پنل در فایرباگ دارای یک سری تنظیمات است که Options Menu نام دارد. تب HTML هم دارای یک سری تنظیمات است که دانشتن آنها بسیار به شما کمک خواهد کرد.
این منو با کلیک کردن بروی فلش تب () یا راست کلیک کردن بروی تب ظاهر میشود.
- Show Full Text
در صورت فعال بودن ، متون بصورت کامل نمایش داده میشوند ، در غیراینصورت بصورت خلاصه شده نمایش داده میشوند.
- Show White Space
در صورت فعال بودن ، فضاهای خالی ، کرکترهای خط جدید و ... را نمایش میدهد.
- Show Comments
در صورت فعال بودن ، کامنتها را هم نمایش میدهد
- سه گزینه ی Show Entities As Symbols ، Show Entities As Names و Show Entities As Unicode ، نوع نمایش کرکترهای ویژه را تعیین میکنند.
- Highlight Changes
در صورت فعال بودن ، تگ تغییر یافته توسط JavaScript (یا تگ والدی که قابل مشاهده باشد) Highlight میشود
- Expand Changes
در صورت فعال بودن ، زمان تغییر دادن یک تگ توسط JavaScript ، والدهای آن تگ باز (Expand) میشوند
- Scroll Changes Into View
در صورت فعال بودن این گزینه ، هنگام تغییر یک تگ در صفحه توسط JavaScript ، قسمت NodeView به قسمت تغییر بافته حرکت میکند.
(فعال بودن این گزینه هنگام بررسی سایت هایی که اسلایدر یا سیستم هایی مشابه دارند ، باعث میشه که نتوانید بروی قسمتهای سایت تمرکز کنید و مدام اسکرول به قسمت تغییرات منتقل میشود.)
- Shade Box Model
در صورت فعال بودن ، فضای margin , padding و content را به شکلی که در بالا گفته شد نمایش میدهد ، در غیر اینصورت فقط یک خط دور تگ نشان میدهد.
- Show Quick Info Box
در صورت فعال بودن ، یک پاپآپ به همراه اطلاعات مختصری از تگ در صفحه نمایش میدهد.
Context Menu
اگر بروی یک تگ راست کلیک کنید ، یک منو نمایش داده میشود ، در این قسمت با گزینههای این منو آشنا میشویم.
- Copy HTML
خود تگ و محتوایش را بصورت HTML در حافظه کپی میکند.
- Copy innerHTML
محتوای تگ را در حافظه کپی میکند.
- Copy XPath
آدرس XPath تگ را در حافظه کپی میکند.
- Copy CSS Path
CSS Selector تگ را در حافظه کپی میکند.
- Log Events
رویدادهای تگ را در پنل Console ثبت میکند. (کلیک موس ، فشردن کلید ، ...)
برای لغو لاگ کردن ، مجددا بروی تگ راست کلیک کرده و این گزینه را از حالت انتخاب خارج کنید.
- Scroll Into View
صفحه را به جایی که تگ قابل نمایش است منتقل میکند.
- New Attribute...
یک attribute جدید به تگ اضافه میکند.
برای لغو عملیات ، دکمهی Esc را بزنید.
- Edit Attribute "<attribute name>"...
اگر بروی یک attribute راست کلیک کرده باشید ، این گزینه و گزینهی بعدی را مشاهده خواهید کرد.
معادل کلیک بروی نام attribute است ، نام را به حالت ویرایش درمی آورد.
- Delete Attribute "<attribute name>"
attribute را حذف میکند.
- Edit HTML...
تگ را به حالت ویرایش میبرد.
معادل انتخاب تگ ، زدن کلید Edit است.
- Delete Element
تگ را حذف میکند.
راه دیگر حذف یک تگ ، انتخاب تگ و فشردن کلید Del از کیبورد است.
- Expand/Contract All
تگ و Childهایش را باز/بسته میکند. (بجز تگ های <script> , <style> , <link>)
میتوان با ترکیب کلیدShift + * هم این کار را انجام داد که در این حالت تگهای فوق هم شامل باز/بسته شدن میشوند.
- Break On Attribute Change
مانع اجرای کد JavaScript ای که attribute تگ را تغییر میدهد میشود و فایرباگ به خطی که باعث این عمل شده است در پنل Script منتقل میشود.
به عبارتی دیگر یک Break Point در خط JavaScript ای که باعث ویرایش attribute میشود قرار میدهد.
- Break On Child Addition or Removal
مشابه توضیح قبل ، Break Point را در خطی که باعث اضافه/حذف شدن تگِ Child شده است قرار میدهد.
- Break On Element Removal
مشابه توضیح قبل ، Break Point را در خطی که باعث حذف شدن تگ شده است قرار میدهد.
- Inspect in DOM Tab
تگ فعلی را در پنل DOM ، برای بررسی باز میکند.