اشتراکها
اشتراکها
خلاصهای از Tag Helpers در MVC6
نظرات مطالب
Symbols در ES 6
به jQuery 2.2 پشتیبانی از Symbolها اضافه شدهاست. به این معنا که اکنون میتوان از حلقههای for of بر روی المانهای آن استفاده کرد:
for (element of $elements) { console.log(element); }
نظرات مطالب
خودکارسازی فرآیند نگاشت اشیاء در AutoMapper
ممنون از پاسختون؛ تنظیمات رجیستری مربوط به اتومپر من به این صورته:
همانطور که ملاحظه میکنید تنها یک وهله از کلاس MapperConfiguration به صورت Singleton تهیه و از آن برای تهیه وهله از IMapper
اگه جایی اشتباه کردم ممنون میشم راهنمایی کنید.
public class AutomapperRegistry : Registry { public AutomapperRegistry() { For<MapperConfiguration>().Use("", ctx => { var config = new MapperConfiguration(cfg => { AutomapperConfig.setup(cfg, ctx); }); config.AssertConfigurationIsValid(); return config; }).Singleton(); For<IMapper>() .HttpContextScoped() .Use(ctx => ctx.GetInstance<MapperConfiguration>().CreateMapper(ctx.GetInstance)); } }
استفاده میشه و برای تنظیمات مپ از متدهای استاتیک آن استفاده نمیکنم و به این صورته:
public static class AutomapperConfig { public static void setup(IMapperConfigurationExpression mappconfig, IContext ctx) { configureAutoMapper(mappconfig, ctx); } private static void configureAutoMapper(IMapperConfigurationExpression mappconfig, IContext ctx) { var profiles = ctx.GetAllInstances<AutoMapper.Profile>().ToList(); foreach (var profile in profiles) { mappconfig.AddProfile(profile); } var types = Assembly.GetExecutingAssembly().GetExportedTypes(); LoadStandardMappings(types, mappconfig); LoadCustomMappings(types, mappconfig); } private static void LoadStandardMappings(IEnumerable<Type> types, IMapperConfigurationExpression mapper) { var maps = (from t in types from i in t.GetInterfaces() where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>) && !t.IsAbstract && !t.IsInterface select new { Source = i.GetGenericArguments()[0], Destination = t }).ToArray(); foreach (var map in maps) { mapper.CreateMap(map.Source, map.Destination); } } private static void LoadCustomMappings(IEnumerable<Type> types, IMapperConfigurationExpression mapper) { var maps = (from t in types from i in t.GetInterfaces() where typeof(IHaveCustomMappings).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface select (IHaveCustomMappings)Activator.CreateInstance(t)).ToArray(); foreach (var map in maps) { map.CreateMappings(mapper); } } }
- data binding یعنی دقیقا به روز شدن اطلاعات با تغییرات کاربر. اگر مدنظر شما نیست، به صورت دستی آنرا مدیریت کنید. ابتدا کار اتصال به رخداد blur را انجام دهید:
و بعد تعریف متد معادل آن در کلاس کامپوننت:
+ Observableها دارای متدی هستند به نام debounceTime که برای همین منظور طراحی شدهاست. یک مثال:
البته این مورد بر روی async validation تاثیری ندارد. برای رفع این مشکل میتوان از راه حلی مانند «Debouncing Angular 2 Input Component» و یا «How to add debounce time to an async validator in angular 2» استفاده کرد (فعلا؛ در زمان نگارش این مطلب).
<input type="text" [(ngModel)]="myModel" (blur)="onBlurMethod()">
export class AppComponent { myModel: any; constructor(){ this.myModel = '123'; } onBlurMethod(){ alert(this.myModel); } }
+ Observableها دارای متدی هستند به نام debounceTime که برای همین منظور طراحی شدهاست. یک مثال:
export class AppComponent { searchForm: ControlGroup; results: Observable<any[]>; constructor(private http: Http) { let searchField = new Control(); this.searchForm = new ControlGroup({searchField}); this.results = searchField.valueChanges .debounceTime(500) .switchMap((val:string) => { return this.search(val); }); }
اگر بخواهیم یک Attribute سفارشی را برای اعتبارسنجی ایجاد کنیم، معمولا یک کلاس را ایجاد کرده و از ValidationAttribute ارث بری میکنیم و سپس متد IsValid آنرا override میکنیم؛ با توجه به نیازی که به آن Attribute داریم. به عنوان مثال در ادامه یک Attribute را ایجاد کردهایم که عمل مقایسهی دو خاصیت را انجام میدهد و اگر مقدار خاصیتی که ویژگی LowerThan بر روی آن قرار دارد، از مقدار خاصیت دیگری که باید با آن مقایسه شود، کمتر نباشد، یک خطا را به ModelState اضافه میکنیم:
ابتدا مقدار خاصیت مورد نظر را که میخواهیم با آن مقایسه شود، با استفاده از رفلکشن گرفتهایم و آن را در متغییر dependentPropertyValue ذخیره میکنیم. در ادامه مقدار Name را با استفاده از رفلکشن از DisplayAttribute میخوانیم و سپس عمل مقایسه را انجام میدهیم که اگر مقدار خاصیتی که ویژگی LowerThan بر روی آن قرار دارد، از مقدار خاصیت مورد نظر که مقدار آن را با استفاده از رفلکشن خواندهایم، کمتر نباشد، یک خطا را به ModelState اضافه میکنیم.
اما یک مشکل! این عمل فقط در سمت سرور بررسی میشود و هنگامیکه ModelState.IsValid را در اکشن متد فراخوانی میکنیم، عمل اعتبارسنجی انجام میشود. یعنی همهی دادهها به سمت سرور ارسال میشوند و اگر خطایی در ModelState وجود داشته باشد، کاربر مجددا باید دادهها را ارسال کند.
اما میتوان با استفاده از اینترفیس IClientModelValidator، عمل اعتبارسنجی را برای این ویژگی در سمت کلاینت انجام داد. برای انجام این کار ابتدا باید از اینترفیس IClientModelValidator ارث بری کنیم و متد AddValidation آن را پیاده سازی کنیم.
اینترفیس IClientModelValidator، یک متد به نام AddValidation دارد که این امکان را فراهم میکند تا بتوانیم اعتبارسنجی را در سمت کلاینت انجام دهیم. در ادامه باید با استفاده از JQuery اعتبارسنجی مخصوص این ویژگی را در سمت کلاینت پیاده سازی کنیم. در متد AddValidation فقط اسم تابع و پارامترهای مورد نیاز در سمت کلاینت را مشخص میکنیم. به عنوان مثال در مثال بالا یک تابع را معرفی کردهایم به نام lowerthan که بعدا باید آنرا در سمت کلاینت پیاده سازی کنیم و نام خاصیتی را که باید با آن مقایسه شود، با نام data-val-dependentpropertyname معرفی کردهایم. در کد زیر، این اعتبار سنجی سمت کلاینت را پیاده سازی کرده ایم. lowerthan نام متدی است که آنرا در متد AddValidation اضافه کردیم. مقدار value همان مقدار خاصیتی است که ویژگی LowerThan بر روی آن قرار دارد و otherPropId نام خاصیتی است که باید با آن مقایسه شود که آنرا از element خواندهایم:
کدهای جاواسکریپتی بالا را در یک فایل جدید به نام LowerThan.js ذخیره کردهایم که باید آن را به صفحه خود اضافه کنیم:
سپس برای استفاده، باید ویژگی LowerThan را بر روی خاصیت مورد نظر قرار دهیم؛ مانند زیر:
و در نهایت اگر مقدار خاصیت Experience که ویژگی LowerThan بر روی آن قرار دارد، از مقدار خاصیت Age که باید با آن مقایسه شود، کمتر باشد، true برگردانده میشود؛ اما اگر بزرگتر یا مساوی باشد، متن خطایی را که در متد AddValidation اضافه کردیم، نشان داده خواهد شد.
public class LowerThanAttribute : ValidationAttribute { public LowerThanAttribute(string dependentPropertyName) { DependentPropertyName = dependentPropertyName; } public string DependentPropertyName { get; set; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { int? currentPropertyValue = value as int?; currentPropertyValue ??= 0; var typeInfo = validationContext.ObjectInstance.GetType(); var dependentPropertyValue = Convert.ToInt32(typeInfo.GetProperty(DependentPropertyName) .GetValue(validationContext.ObjectInstance, null)); var displayDependentProperyName = typeInfo.GetProperty(DependentPropertyName) .GetCustomAttributes(typeof(DisplayAttribute), false) .Cast<DisplayAttribute>() .FirstOrDefault()?.Name; if (!(currentPropertyValue.Value < dependentPropertyValue)) { return new ValidationResult("مقدار {0} باید کمتر باشد از " + displayDependentProperyName); } return ValidationResult.Success; } }
اما یک مشکل! این عمل فقط در سمت سرور بررسی میشود و هنگامیکه ModelState.IsValid را در اکشن متد فراخوانی میکنیم، عمل اعتبارسنجی انجام میشود. یعنی همهی دادهها به سمت سرور ارسال میشوند و اگر خطایی در ModelState وجود داشته باشد، کاربر مجددا باید دادهها را ارسال کند.
اما میتوان با استفاده از اینترفیس IClientModelValidator، عمل اعتبارسنجی را برای این ویژگی در سمت کلاینت انجام داد. برای انجام این کار ابتدا باید از اینترفیس IClientModelValidator ارث بری کنیم و متد AddValidation آن را پیاده سازی کنیم.
public class LowerThanAttribute : ValidationAttribute, IClientModelValidator { public LowerThanAttribute(string dependentPropertyName) { DependentPropertyName = dependentPropertyName; } public string DependentPropertyName { get; set; } public void AddValidation(ClientModelValidationContext context) { var displayCurrentProperyName = context.ModelMetadata.ContainerMetadata .ModelType.GetProperty(context.ModelMetadata.PropertyName) .GetCustomAttributes(typeof(DisplayAttribute), false) .Cast<DisplayAttribute>() .FirstOrDefault()?.Name; var displayDependentProperyName = context.ModelMetadata.ContainerMetadata .ModelType.GetProperty(DependentPropertyName) .GetCustomAttributes(typeof(DisplayAttribute), false) .Cast<DisplayAttribute>() .FirstOrDefault()?.Name; MergeAttribute(context.Attributes, "data-val", "true"); MergeAttribute(context.Attributes, "data-val-lowerthan", $"{displayCurrentProperyName} باید کمتر باشد از {displayDependentProperyName}"); MergeAttribute(context.Attributes, "data-val-dependentpropertyname", "#" + DependentPropertyName); } private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value) { if (attributes.ContainsKey(key)) { return false; } attributes.Add(key, value); return true; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { int? currentPropertyValue = value as int?; currentPropertyValue ??= 0; var typeInfo = validationContext.ObjectInstance.GetType(); var dependentPropertyValue = Convert.ToInt32(typeInfo.GetProperty(DependentPropertyName) .GetValue(validationContext.ObjectInstance, null)); var displayCurrentProperyName = typeInfo.GetProperty(DependentPropertyName) .GetCustomAttributes(typeof(DisplayAttribute), false) .Cast<DisplayAttribute>() .FirstOrDefault()?.Name; if (!(currentPropertyValue.Value < dependentPropertyValue)) { return new ValidationResult("مقدار {0} باید کمتر باشد از " + displayCurrentProperyName); } return ValidationResult.Success; } }
jQuery.validator.addMethod("lowerthan", function (value, element, param) { var otherPropId = $(element).data('val-dependentpropertyname'); if (otherPropId) { var otherProp = $(otherPropId); if (otherProp) { var otherVal = otherProp.val(); if (parseInt(otherVal) > parseInt(value)) { return true; } return false; } } return true; }); jQuery.validator.unobtrusive.adapters.addBool("lowerthan");
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script> <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script> <script src="~/js/LowerThan.js"></script>
public class User { [Required] [Display(Name ="نام کاربری")] public string Username { get; set; } [Required] [Display(Name = "سن")] public int Age { get; set; } [LowerThan(nameof(Age))] [Required] [Display(Name = "سابقه کار")] public int Experience { get; set; } }
مطالب دورهها
بررسی حالتهای مختلف نصب RavenDB
چهار روش مختلف برای نصب، استفاده و توزیع RavenDB وجود دارند. سادهترین روش آنرا که اجرای فایل Raven.Server.exe است، تاکنون بررسی کردیم. این روش صرفا جهت دیباگ و کار برنامه نویسی مناسب است. در ادامه سه روش دیگر را بررسی خواهیم کرد.
الف) استفاده از RavenDB در حالت مدفون شده یا Embedded
حالت Embedded به این معنا است که RavenDB درون پروسه برنامه شما اجرا خواهد شد و نه به صورت پروسهای مجزا. این حالت برای ارائه ساده برنامههای دسکتاپ بسیار مناسب است؛ یا حتی توزیع برنامههای سبک ASP.NET بدون نیاز به نصب بانک اطلاعاتی خاصی بر روی وب سرور.
برای کار با RavenDB در حالت Embedded ابتدا فایلهای مورد نیاز آنرا از طریق نیوگت دریافت کنید:
در این حالت فایل کلاینت مورد نیاز، اسمبلی Raven.Client.Embedded.dll خواهد بود. سپس در کدهای قبلی خود بجای استفاده از new DocumentStore، اینبار خواهیم داشت new EmbeddableDocumentStore.
سایر قسمتهای برنامه نیازی به تغییر نخواهند داشت.
امکان تعریف DataDirectory در فایل کانفیگ برنامه نیز وجود دارد. فقط در این حالت باید دقت داشت که نام مسیر، با DataDir شروع میشود و نه DataDirectory :
سپس همانند قبل، مقدار خاصیت رشته اتصالی EmbeddableDocumentStore به نام مدخل فوق باید تنظیم گردد.
چند نکته جالب در مورد حالت Embedded
- امکان اجرای درون حافظهای RavenDB نیز وجود دارد:
در اینجا فقط کافی است خاصیت RunInMemory شیء EmbeddableDocumentStore به true تنظیم شود. این مورد بسیار مناسب است برای انجام آزمونهای واحد بسیار سریع که پس از پایان کار برنامه، اثری از بانک اطلاعاتی آن باقی نخواهد ماند.
- اجرای حالت Embedded به صورت Embedded HTTP:
در حالت Embedded دیگر دسترسی به برنامه سیلورلایت Raven studio وجود ندارد. اگر علاقمند به کار با آن بودید، خاصیت UseEmbeddedHttpServer شیء EmbeddableDocumentStore را به true تنظیم کنید. سپس فایل Raven.Studio.xap را در ریشه وب سایت خود قرار دهید. اکنون مانند قبل آدرس localhost:8080/raven/studio.html برقرار خواهد بود.
همچنین سرور Http این بانک اطلاعاتی را نیز میتوان دستی راه اندازی کرد. متد NonAdminHttp.EnsureCanListenToWhenInNonAdminContext بررسی میکند که آیا برنامه مجوز راه اندازی یک سرور را بر روی پورت مثلا 8080 دارد یا خیر.
ب) نصب RavenDB به صورت سرویس ویندوز NT
اگر مایل باشیم تا RavenDB را نیز مانند SQL Server به صورت یک سرویس ویندوز NT نصب کنیم تا همواره در پس زمینه سرور در حال اجرا باشد، کنسول پاورشل ویندوز را گشوده و سپس فرمان ذیل را صادر کنید:
اکنون اگر به کنسول مدیریتی سرویسهای ویندوز یا services.msc مراجعه کنید، ravendb را به صورت یک آیتم جدید در لیست سرویسهای ویندوز خواهید یافت.
و اگر خواستید این سرویس را عزل کنید، دستور ذیل را در پاورشل ویندوز صادر کنید:
ج) نصب RavenDB به صورت یک پروسه IIS (یا اجرا شده توسط IIS)
فایلهای مورد نیاز حالت اجرای RavenDB را به صورت یک پروسه مجزای IIS از نیوگت دریافت کنید:
در این حالت، پوشه bin، فایل xap و فایل کانفیگ برنامه وب مورد نیاز دریافت خواهند شد. پس از آن، تنها کافی است یک دایرکتوری مجازی را در IIS به این پوشه جدید اختصاص داده و همچنین بهتر است یک Application pool جدید را نیز برای آن تهیه کنید تا واقعا این برنامه در پروسهی مجزای خاص خودش اجرا شود. حتی در این حالت میتوان شماره پورت دیگری را به این برنامه اختصاص داد. به علاوه در این حالت تنظیمات Recycling مربوط به IIS را هم باید مدنظر داشت (در قسمت تنظیمات Application pool برنامه) و مثلا تنظیم کرد که برنامه پس از چه مدت فعال نبودن از حافظه خارج شود.
یک نکته
تمام بستههای مورد نیاز را یکجا از آدرس http://ravendb.net/download نیز میتوان دریافت کرد. در نگارشهای جدید، بسته نصاب نیز برای این بانک اطلاعاتی تهیه شده است که برای نمونه توزیع آنرا جهت حالت نصب در IIS سادهتر میکند.
الف) استفاده از RavenDB در حالت مدفون شده یا Embedded
حالت Embedded به این معنا است که RavenDB درون پروسه برنامه شما اجرا خواهد شد و نه به صورت پروسهای مجزا. این حالت برای ارائه ساده برنامههای دسکتاپ بسیار مناسب است؛ یا حتی توزیع برنامههای سبک ASP.NET بدون نیاز به نصب بانک اطلاعاتی خاصی بر روی وب سرور.
برای کار با RavenDB در حالت Embedded ابتدا فایلهای مورد نیاز آنرا از طریق نیوگت دریافت کنید:
PM> Install-Package RavenDB.Embedded -Pre
var documentStore = new EmbeddableDocumentStore { DataDirectory = @"~/app_data/ravendb" }; documentStore.Initialize();
امکان تعریف DataDirectory در فایل کانفیگ برنامه نیز وجود دارد. فقط در این حالت باید دقت داشت که نام مسیر، با DataDir شروع میشود و نه DataDirectory :
<connectionStrings> <add name="Local" connectionString="DataDir = ~\Data"/>
چند نکته جالب در مورد حالت Embedded
- امکان اجرای درون حافظهای RavenDB نیز وجود دارد:
var documentStore = new EmbeddableDocumentStore{RunInMemory = true}.Initialize()
- اجرای حالت Embedded به صورت Embedded HTTP:
در حالت Embedded دیگر دسترسی به برنامه سیلورلایت Raven studio وجود ندارد. اگر علاقمند به کار با آن بودید، خاصیت UseEmbeddedHttpServer شیء EmbeddableDocumentStore را به true تنظیم کنید. سپس فایل Raven.Studio.xap را در ریشه وب سایت خود قرار دهید. اکنون مانند قبل آدرس localhost:8080/raven/studio.html برقرار خواهد بود.
همچنین سرور Http این بانک اطلاعاتی را نیز میتوان دستی راه اندازی کرد. متد NonAdminHttp.EnsureCanListenToWhenInNonAdminContext بررسی میکند که آیا برنامه مجوز راه اندازی یک سرور را بر روی پورت مثلا 8080 دارد یا خیر.
NonAdminHttp.EnsureCanListenToWhenInNonAdminContext(8080); // Start the HTTP server manually var server = new RavenDbHttpServer(documentStore.Configuration, documentStore.DocumentDatabase); server.Start();
ب) نصب RavenDB به صورت سرویس ویندوز NT
اگر مایل باشیم تا RavenDB را نیز مانند SQL Server به صورت یک سرویس ویندوز NT نصب کنیم تا همواره در پس زمینه سرور در حال اجرا باشد، کنسول پاورشل ویندوز را گشوده و سپس فرمان ذیل را صادر کنید:
d:\ravendb\server> .\raven.server.exe /install
و اگر خواستید این سرویس را عزل کنید، دستور ذیل را در پاورشل ویندوز صادر کنید:
d:\ravendb\server> .\raven.server.exe /uninstall
ج) نصب RavenDB به صورت یک پروسه IIS (یا اجرا شده توسط IIS)
فایلهای مورد نیاز حالت اجرای RavenDB را به صورت یک پروسه مجزای IIS از نیوگت دریافت کنید:
PM> Install-Package RavenDB.AspNetHost -Pre
یک نکته
تمام بستههای مورد نیاز را یکجا از آدرس http://ravendb.net/download نیز میتوان دریافت کرد. در نگارشهای جدید، بسته نصاب نیز برای این بانک اطلاعاتی تهیه شده است که برای نمونه توزیع آنرا جهت حالت نصب در IIS سادهتر میکند.
در ادامه مطلب قبلی آموزش (jQuery) جی کوئری 5# به ادامه بحث میپردازیم.
در پستهای قبلی مروری بر jQuery داشته و در چند پست انواع روشهای انتخاب عناصر صفحه وب را توسط jQuery بررسی کردیم. در پستهای آینده با مباحث پیشرفتهتری همچون انجام عملیاتی روی المانهای انتخاب شده، خواهیم پرداخت؛ امید است مفید واقع شود.
٢ -٢ - ایجاد عناصر HTML جدید
گاهی اوقات نیاز میشود که یک یا چند عنصر جدید به صفحهی در حال اجرا اضافه شوند. این حالت میتواند به سادگی قرار گرفتن یک متن در جایی از صفحه و یا به پیچیدگی ایجاد و نمایش یک جدول حاوی اطلاعات دریافت شده از بانک اطلاعاتی باشد.
ایجاد عناصر به صورت پویا در یک صفحه در حال اجرا کار ساده ای برای jQuery میباشد، زیرا همانطور که در پست آموزش (jQuery) جی کوئری 1# مشاهده کردیم ()$ با دریافت دستور ساخت یک عنصر HTML آن را در هر زمان ایجاد میکند، دستور زیر :
یک عنصر div ایجاد میکند و آماده افزودن آن به صفحه در هر زمان میباشد.تمامی توابع و متدهایی را که تاکنون بررسی کردیم قابل اعمال بروی اینگونه اشیا نیز میباشند. شاید در ابتدا ایجاد عناصر به این شکل خیلی مفید به نظر نرسد، اما زمانی که بخواهیم کارهای حرفه ایتری انجام دهیم؛ برای مثال کار با AJAX، خواهیم دید که تا چه اندازه ایجاد عناصر به این روش میتواند مفید باشد.
دقت کنید که یک راه کوتاهتر نیز برای ایجاد یک عنصر <div> خالی وجود دارد که به شکل زیر است:
اما برای ایجاد عناصری که خود میتوانند حاوی عناصر دیگر باشند استفاده از راههای کوتاه توصیه نمیشود مانند نوشتن تگ <script> .اما راههای زیادی برای انجام اینکار وجود دارد.
برای اینکه مزه اینکار را بچشید بد نیست نگاهی به مثال زیر بیندازید (نگران قسمتهای نامفهوم نباشید به مرور با آنها آشنا خواهیم شد):
در این مثال ابتدا ما یک المان div ایجاد کردیم که دارای کلاس foo میباشد، و خود شامل یک div دیگر است. در ادامه div که دارای کلاس foo بوده را انتخاب کرده و رویداد کلیک را به آن بایند کردیم. و در انتها این div را با محتویاتش به المانی با Id=someParentDiv در سلسله مراتب DOM اضافه میکند.
برای اجرا این کد میتوانید کد آن را دانلود کرده و فایل chapter2/new.divs.htmlرا اجرا کنید خروجی مانند تصویر زیر خواهد بود:
جهت تکمیل مطلب فعلی یک مثال کاملتر از این سایت جهت بررسی انتخاب کردم:
در این مثال کمی پیشرفتهتر یک div ایجاد شده کلاس test را برای آن قرار داده و عنوان ان را برابر text قرار میدهد و یک رویداد کلیک برای آن تعریف میکند و در نهایت آن را به body سایت اضافه میکند.
با توجه به اینکه مطالب بعدی طولانی بوده و تقریبا مبحث جدایی است؛ در پست بعدی به بررسی توابع و متدهای مدیریت مجموعه انتخاب شده خواهیم پرداخت.
در پستهای قبلی مروری بر jQuery داشته و در چند پست انواع روشهای انتخاب عناصر صفحه وب را توسط jQuery بررسی کردیم. در پستهای آینده با مباحث پیشرفتهتری همچون انجام عملیاتی روی المانهای انتخاب شده، خواهیم پرداخت؛ امید است مفید واقع شود.
٢ -٢ - ایجاد عناصر HTML جدید
گاهی اوقات نیاز میشود که یک یا چند عنصر جدید به صفحهی در حال اجرا اضافه شوند. این حالت میتواند به سادگی قرار گرفتن یک متن در جایی از صفحه و یا به پیچیدگی ایجاد و نمایش یک جدول حاوی اطلاعات دریافت شده از بانک اطلاعاتی باشد.
ایجاد عناصر به صورت پویا در یک صفحه در حال اجرا کار ساده ای برای jQuery میباشد، زیرا همانطور که در پست آموزش (jQuery) جی کوئری 1# مشاهده کردیم ()$ با دریافت دستور ساخت یک عنصر HTML آن را در هر زمان ایجاد میکند، دستور زیر :
$("<div>Hello</div>")
دقت کنید که یک راه کوتاهتر نیز برای ایجاد یک عنصر <div> خالی وجود دارد که به شکل زیر است:
$("<div>") // همه اینها معادل هستند
$("<div></div>")
$("<div/>")
برای اینکه مزه اینکار را بچشید بد نیست نگاهی به مثال زیر بیندازید (نگران قسمتهای نامفهوم نباشید به مرور با آنها آشنا خواهیم شد):
$("<div class='foo'>I have foo!</div><div>I don't</div>") .filter(".foo").click(function() { alert("I'm foo!"); }).end().appendTo("#someParentDiv");
برای اجرا این کد میتوانید کد آن را دانلود کرده و فایل chapter2/new.divs.htmlرا اجرا کنید خروجی مانند تصویر زیر خواهد بود:
جهت تکمیل مطلب فعلی یک مثال کاملتر از این سایت جهت بررسی انتخاب کردم:
$( "<div/>", { "class": "test", text: "Click me!", click: function() { $( this ).toggleClass( "test" ); } }).appendTo( "body" );
با توجه به اینکه مطالب بعدی طولانی بوده و تقریبا مبحث جدایی است؛ در پست بعدی به بررسی توابع و متدهای مدیریت مجموعه انتخاب شده خواهیم پرداخت.
در حالت عادی، بریز متادیتای خود را از سرور دریافت میکند. ولی میتوان از یک فایل جاوا اسکریپتی نیز آنرا فراهم کرد. ظاهرا این روش مناسبترین روش برای خواندن متا دیتا میباشد.
مزایای بارگذاری متادیتا از طریق یک فایل جاوااسکریپتی
در ابتدا فایل metadata.js را در مسیر Scripts ایجاد نمایید و ارجاعی به آن را در layaout.cshtml قرار دهید:
کارهایی را که باید انجام بدهیم:
2- ایمپورت متادیتای جاوااسکریپتی در سمت کلاینت:
ما متا دیتای تولید شدهی در سرور را گرفته و در یک متغیر جاوااسکریپتی قرار میدهیم و محتویات این متغیر را در MetadataStore ایمپورت میکنیم.
مزایای بارگذاری متادیتا از طریق یک فایل جاوااسکریپتی
- کاهش سایز متادیتا (برای اپلیکشن خودم، سایز متادیتای دریافتی از سرور، 105 کیلوبایت بود و بعد از ایجاد این فایل اسکریپتی و اعمال کردن gzip به آن، به 10 کیلو بایت کاهش یافت.)
- بارگذاری سریعتر برنامه
-کش کردن فایل جاوااسکریپتی
در ابتدا فایل metadata.js را در مسیر Scripts ایجاد نمایید و ارجاعی به آن را در layaout.cshtml قرار دهید:
<script src="~/Scripts/metadata.js"></script>
کارهایی را که باید انجام بدهیم:
1- ایجاد متادیتا در سمت سرور:
1.1- دریافت متادیتا از دیتابیس
1.2-stringify های متادیتا
1.3 -نوشتن متادیتا در فایل metadata.js
private static void WriteMetadata() { var metadata = new EFContextProvider<ApplicationDbContext>().Metadata();//1.1 var fileName =HttpContext.Current.Server.MapPath("~/Scripts/metadata/metadata.js"); const string prefix = "var metadata = JSON.stringify(";//1.2 const string postfix = ");"; using (var writer = new StreamWriter(fileName)) { writer.WriteLine(prefix + metadata + postfix);//1.3 } }
2.1- غیرفعال کردن متادیتای سرور.
2.2- ایمپورت کردن متغیر metadata که به صورت سراسری در اپلیکشن قابل دسترسی میباشد.
2.3 -ایجاد کردن EntityManager.
var serviceName = 'breeze/northwind'; // your service root here function createEntityManager() { var dataService = new breeze.DataService({ serviceName: serviceName, hasServerMetadata: false // 2.1 }); var metadataStore = new breeze.MetadataStore({ namingConvention: camelCaseConvention // if you use this convention }); // initialize it from the application's metadata variable metadataStore.importMetadata(metadata);//2.2 return new breeze.EntityManager({ dataService: dataService, metadataStore: metadataStore });//2.3 }
نظرات اشتراکها
ایجاد یک موتور جستجوی سفارشی جهت search bar فایرفاکس
این موارد هست که توسط افزونه extensions list dumper تهیه شد:
- Adblock Plus 2.1.2 http://adblockplus.org/en/ - Add to Search Bar 2.0 http://firefox.maltekraus.de/extensions/add-to-search-bar - Calculator 1.1.27 http://code.google.com/p/firefoxcalculator/ - CodeBurner for Firebug 1.6 http://tools.sitepoint.com/codeburner - ColorZilla 2.8.1 http://www.colorzilla.com/ - Cookies Manager+ 1.5.1 https://addons.mozilla.org/en-US/firefox/addon/cookies-manager-plus/ - CSS Usage 0.2.9 http://spaghetticoder.org/cssusage/ - DOM Inspector 2.0.12 http://www.mozilla.org/projects/inspector/ - Extension List Dumper 1.15.2 http://www.sogame.cat/ - File Title 1.4 http://www.jasnapaka.com/mozilla/filetitle/ - Firebug 1.10.2 http://www.getfirebug.com/ - FireDiff 1.2.0 http://www.incaseofstairs.com/firediff - Firefinder for Firebug 1.04 http://robertnyman.com/firefinder/ - FireFTP 2.0.7 http://fireftp.mozdev.org - FireQuery 1.2 http://firequery.binaryage.com - Forecastfox 2.2.1 http://www.getforecastfox.com/ - Greasemonkey 1.0 http://www.greasespot.net/ - HighlightAll 1.6 http://jgoudey.free.fr/highlightall/ - HttpFox 0.8.11 http://code.google.com/p/httpfox/ - IranianCalendar 3.1.20081222 http://www.alavi.us/jcal/ - Linky 3.0.0 http://gemal.dk/mozilla/linky.html - MeasureIt 0.4.10 http://frayd.us/ - Open With 5.2.1 http://www.darktrojan.net/software/addons/openwith/ - PDF Download 3.0.0.2 http://www.pdfdownload.org - Pixel Perfect 1.7.1 http://www.pixelperfectplugin.com/ - Pray Times! 1.1.7 http://praytimes.org/ - Proxy Selector 0.80.7 http://addons.mozilla.org - Right-Click-Link 1.1.5 http://rickardandersson.com/ - SearchPreview 5.9 http://searchpreview.de/ - Server Spy 0.2.1 http://www.jacquet80.eu/mozilla/exts/ServerSpy/ - Session Manager 0.7.9 http://sessionmanager.mozdev.org/ - Show MyIP 0.8 http://www.tsql.de/download/firefox-addon-ip-adresse-ip-address - Show Picture 2.7 https://addons.mozilla.org/en-US/firefox/addon/show-picture/?src=api - Showcase 0.9.5.8 http://showcase.uworks.net/ - Snap Links Plus 2.2.1 http://snaplinks.mozdev.org/ - Sothink Web Video Downloader for Firefox 6.8 http://www.web-video-downloader.com - Speed Dial 0.9.6.8 http://speeddial.uworks.net/ - SQLite Manager 0.7.7 http://sqlite-manager.googlecode.com/ - Stylish 1.2.6 http://userstyles.org/ - Subtitle Matcher 0.3.4 http://ds6.ovh.org/hashsubtitles/subtitle_matcher_firefox_extensions.php - Tilt 1.0.1 http://blog.mozilla.com/tilt/ - UnMHT 5.7.5 http://www.unmht.org/unmht/en_index.html - UnPlug 2.050 http://unplug.dbatley.com/ - User Agent Switcher 0.7.3 http://chrispederick.com/work/user-agent-switcher/ - View Source Chart 3.05 http://zigrat.com - Viewstate Size 1.0.4 http://www.kirkov.dk/projects/firefox/viewstatesize - Web Developer 1.2.1 http://chrispederick.com/work/web-developer/firefox/ - YSlow 3.1.4 http://developer.yahoo.com/yslow