ENOTEMPTY: directory not empty, rmdir F:\...\dist\my-lib\lib
projects/YourProjectName/architect/build/options
ENOTEMPTY: directory not empty, rmdir F:\...\dist\my-lib\lib
projects/YourProjectName/architect/build/options
ترجیحا نوع Typescript را انتخاب کردم. البته در داخل فایل ts. امکان نوشتن جاوا اسکریپت هم هست. بعد از ایجاد پروژه اگر با تصویری شبیه به تصویر زیر روبرو شدید، در نتیجه تنظیمات نصب و راه اندازی به درستی صورت گرفته است.
اگر به قسمت solution explorer دقت کنید، فایلی به نام config.xml را مشاهده خواهید کرد. با کلیک بر روی این فایل، یک صفحهی گرافیکی باز خواهد شد که این امکان را به شما میدهد که پلاگینهای مورد نیاز خود، تنظیمات مربوط به نرم افزار تولیدی (مانند تنظیم ورژن ویندوزی که میخواهید app شما بر روی آن اجرا شود) و تنظیمات مربوط به هر یک از پلتفرمها را به صورت مجزا در اختیار داشته باشید.
یک فایل index.html هم در قالب پیشفرض قرار داده شده که بعدا میتوانید آن را تغییر دهید و یا صفحات دیگری را اضافه کنید. همان طور که در قسمتهای قبل گفته شد، قرار است ما یک وب اپلیکیشن طراحی کنیم و آن را درون Container بومی Cordova بسته بندی کنیم. لذا محدودیتی برای استفادهی از کتابخانههای مرتبط با CSS ، HTML و JavaScript نداریم و در ادامهی مقالات با مثالهای متعددی از آنها استفاده خواهیم کرد.
در فولدر scripts-->typeings-->cordova-->plugins اینترفیسهایی که برای دسترسی به امکانات بومی دستگاه تلفن فعلا در Cordova پشتیبانی میشوند، قرار گرفته است.
برای استفاده از تکنولوژیهای وب در محیط بومی دستگاه، در طی فرآیند کامپایل، Cordova یک اپلیکیشن را به وسیله دو چیز مهم که در زیر اشاره شده است، خواهد ساخت.
برای یکپارچه شدن APIهای Cordova با وب پیج موجود، اندکی کد نیاز داریم که برای انکار لینکی شبیه لینک زیر را در فایل html خود استفاده میکنیم که فقط بعد از کامپایل وجود خارجی دارد؛ به صورت زیر:
<script src="cordova.js"></script>
در پایان هم برای فهمیدن اینکه APIهای Cordova در دسترس هستند، میتوانیم رخداد مربوط به devicerady را مدیریت کنیم؛ به صورت زیر:
document.addEventListener("deviceready", onDeviceReady, false); function onDeviceReady() { /* INIT */ }
برای مدیریت رخدادهای مربوط به pause و resume هم که نشان دهندهی ادامه برنامه (خارج شدن از حالت pause) و حالت تعلیق هستند، میتوان به شکل زیر عمل کرد:
function onDeviceReady() { // Handle the Cordova pause and resume events document.addEventListener('pause', onPause, false); document.addEventListener('resume', onResume, 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. } function onResume() { // TODO: This application has been reactivated. Restore application state here. }
حال قصد داریم پروژهی خود را که قرار است یک متن ساده را نشان دهد، با استفاده از شبیه ساز اجر ا کنیم. برای این منظور از قسمت toolbar ویژوال استودیو ، Solution Platform خود را انتخاب کنید و سپس میتوانید شبیه ساز مورد نظر خود را انتخاب کرده و برنامه را اجرا کنید. در اینجا محیط مورد نظر من اندروید است و برای این منظور هم میتوانم از شبیه ساز Android Emulator یا Ripple استفاده کنم. به دلیل سرعت کم شبیه ساز اندروید، میتوانید شبیه ساز YouWave را دانلود و اجرا کرده و در قسمتی که شبیه ساز را از toolbar ویژوال انتخاب میکردید، این بار گزینهی Device را انتخاب کنید. بعد از کامپایل برنامهی شما، فایل apk تولید شده بر روی شبیه ساز نصب خواهد شد و شما قادر خواهید بود آنرا اجرا کنید.
نتیجهی نهایی
با شبیه ساز Ripple
مطالعه بیشتر
https://msdn.microsoft.com/en-us/library/dn879821(v=vs.140).aspx
http://blog.falafel.com/getting-started-with-cordova-and-multi-device-hybrid-app-in-visual-studio/
http://www.codeproject.com/Articles/860150/Visual-Studio-and-Apache-Cordova
نکته : وقتی پروژه را برای اولین بار اجرا میکنید شاید کمی طول بکشد تا نتیجهی نهایی را ببنید و آن هم به دلیل این است که ویژوال استودیو باید مجموعهای از package های مورد نیاز Cordova را دانلود کند.
در مقاله بعد با jQuery Mobile آشنا خواهیم شد و یک مثال برای کار کردن با آن در نظر خواهم گرفت.
ادامه دارد ...
<script src="js/kendo.web.min.js" type="text/javascript"></script>
jQuery.fn.myPlugin = function() { //محتویات پلاگین را اینجا مینویسیم };
(function( $ ) { $.fn.myPlugin = function() { //محتویات پلاگین را اینجا مینویسیم }; })( jQuery );
(function($){ $.fn.underline= function() { this.hover(function(){ $(this).css( { text-decoration : underline }) }, function(){ $(this).css( { text-decoration : none } ) }); }; })(jQuery); $("p").underline();
(function( $ ){ $.fn.maxHeight = function() { var max = 0; this.each(function() { max = Math.max( max, $(this).height() ); }); return max; }; })( jQuery );
var tallest = $('div').maxHeight(); // بیشترین ارتفاع عنصر را برمی گرداند
(function( $ ){ $.fn.lockDimensions = function( type ) { return this.each(function() { var $this = $(this); if ( !type || type == 'width' ) { $this.width( $this.width() ); } if ( !type || type == 'height' ) { $this.height( $this.height() ); } }); }; })( jQuery );
$('div').lockDimensions('width').css('color', 'red');
(function( $ ){ $.fn.tooltip = function( options ) { var settings = $.extend( { 'location' : 'top', 'background-color' : 'blue' }, options); return this.each(function() { // Tooltip plugin code here }); }; })( jQuery );
$('div').tooltip({ 'location' : 'left' });
تا اینجای کار ساخت کامپوننتها را با React.createClass که تفاوتی با توسعه (ارث بری) از کلاس React.Component ندارد، انجام دادهایم. اما ساخت کامپوننتها به صورت یک تابع هم مزیتهایی را دارد. اول از همه باید بدانیم که ساخت کامپوننت توسط تابع، بدون وضعیت خواهد بود که به آن Stateless میگویند. به دلیل نداشتن وضعیت، کامپوننتهای تابعی را کمی بهتر میشود برای استفاده مجدد به کار برد. در کامپوننتهای غیر تابعی که Stateful هستند به دلیل احتمال وابستگی وضعیت کامپوننت به خارج از کلاس، مانند مثال قسمت چهارم که کامپوننت در انتظار کلیک یک دکمه خاص توسط کاربر بود، مدیریت استفاده مجدد ازکامپوننت چالش برانگیز خواهد شد.
برای مدیریت بهتر کامپوننتها جهت استفاده مجدد از آنها بهتر است ورودیهای کامپوننت را اعتبارسنجی کنیم. این ورودیها چه برای استفاده داخلی کامپوننت، یا جهت مشخص کردن وضعیت آن، بر رفتار کامپوننت تاثیر زیادی دارند. React مجموعهای از اعتبار سنجیها را دارد که میشود به کامپوننت اضافه کرد. باید توجه داشته باشیم که پیامهای خطای این اعتبارسنجیها فقط در حالت Development Mode قابل استفاده هستند. به زبان ساده اگر از react.min.js استفاده کنید، پیامهای خطا را نخواهید دید. باید فایلها را به نوع react.js تبدیل کنید. اعتبارسنجی React در زمان توسعه و برای توسعه دهندگان استفاده میشود.
مثال نوشیدنیها در قسمت چهارم میتوانست نام نوشیدنی و قیمت آن را نمایش دهد و همچنین میتوانستیم به لیست نوشیدنیها، موردی را اضافه کنیم. اگر ورودی قیمت، اعتبارسنجی نشود، میتوان رشتهای را بجای عدد به عنوان قیمت به کامپوننت ارسال کرد. نحوه اعتبارسنجی قیمت نوشیدنیها به صورت زیر است.
const MenuItem = props => ( <li className="list-group-item"> <span className="badge">{props.price}</span> <p>{props.item}</p> </li> ) MenuItem.propTypes = { price: React.PropTypes.number };
شیء propTypes را به کامپوننت اضافه کردهایم و در تنظیمات آن میتوانیم برای هر پارامتر ورودی یکی از اعضای PropTypes از React را که مناسب حال پارامتر است، انتخاب کنیم. در مثال بالا مشخص کردهایم که ورودی price باید عدد باشد و اگر مثلا رشتهای را بجای عدد ارسال کنیم، پیام خطای زیر را در Console خواهیم داشت.
Warning: Failed prop type: Invalid prop `price` of type `string` supplied to `MenuItem`, expected `number`. in MenuItem (created by Menu) in Menu
یا میتوانستیم از React.PropTypes.number.isRequired استفاده کنیم تا درج مقداری برای این ورودی الزامی باشد. اگر اعتبارسنجیهای React کافی نبودند میتوانیم اعتبارسنجیهای سفارشی خودمان را ایجاد کنیم. در مثال زیر میخواهیم ورودی price بیشتر از 15000 نباشد.
MenuItem.propTypes = { price: (props, price)=>{ if(props[price] > 15000){ return new Error("Too expensive!"); } } };
let MenuItem = React.createClass({ propTypes: { price: React.PropTypes.number } }); class MenuItem extends React.Component{ static propTypes = { price: React.PropTypes.number }; }
نوعهای دیگر برای اعتبارسنجی شامل موارد زیر هستند و البته مرجع تمام اعتبارسنجیهای React را میتوانید در اینجا بررسی کنید.
یکی از امکانات مفید دیگر برای مدیریت مقدارهای ورودی، مشخص کردن مقدار پیشفرضی برای یک پارامتر است. برای مثال اگر برای قیمت یک نوشیدنی مقداری وارد نشد، یک حداقل قیمت برای آن در نظر بگیریم، هر چند که ایده و روشی اشتباه است!
MenuItem.defaultProps = { price: 1000 };
همانطور که میبینید روش کار مشابه با اعتبارسنجی است و برای مشخص کردن مقدار پیشفرض برای React.creatClass از متد getDefaultProps که عضوی از React است، استفاده میکنیم.
let MenuItem = React.createClass({ getDefaultProps() { return { price: 200 } }, render() { return ( <li className="list-group-item"> <span className="badge">{this.props.price}</span> <p>{this.props.item}</p> </li> ); } });
PM> install-package Newtonsoft.Json
var roles = new List<string> { "Admin", "User" }; string json = JsonConvert.SerializeObject(roles, Formatting.Indented);
var jsonString = JsonConvert.SerializeObject(new { Id =1, Name = "Test" }, Formatting.Indented);
var jsonData = JsonConvert.SerializeObject(new { Id = 1, Name = "Test", DateTime = DateTime.Now }, new JsonSerializerSettings { Formatting = Formatting.Indented, Converters = { new JavaScriptDateTimeConverter() } });
{ "Id": 1, "Name": "Test", "DateTime": new Date(1409821985245) }
using (var stream = File.CreateText(@"c:\output.json")) { var jsonSerializer = new JsonSerializer { Formatting = Formatting.Indented }; jsonSerializer.Serialize(stream, new { Id = 1, Name = "Test", DateTime = DateTime.Now }); }
public class User { public int Id { set; get; } public string Name { set; get; } public DateTime DateTime { set; get; } }
var user = JsonConvert.DeserializeObject<User>(jsonData);
var user = JsonConvert.DeserializeObject<User>(jsonData, new JsonSerializerSettings { Converters = { new JavaScriptDateTimeConverter() } });
JsonConvert.PopulateObject(jsonData, user);
var jsonData = JsonConvert.SerializeObject(object, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented });
public class Employee { public string Name { set; get; } } public class Manager : Employee { public IList<Employee> Reports { set; get; } }
var employee = new Employee { Name = "User1" }; var manager1 = new Manager { Name = "User2" }; var manager2 = new Manager { Name = "User3" }; manager1.Reports = new[] { employee, manager2 }; manager2.Reports = new[] { employee };
var list = JsonConvert.SerializeObject(manager1, Formatting.Indented);
{ "Reports": [ { "Name": "User1" }, { "Reports": [ { "Name": "User1" } ], "Name": "User3" } ], "Name": "User2" }
var list = JsonConvert.SerializeObject(manager1, new JsonSerializerSettings { Formatting = Formatting.Indented, TypeNameHandling = TypeNameHandling.Objects, PreserveReferencesHandling = PreserveReferencesHandling.Objects });
{ "$id": "1", "$type": "JsonNetTests.Manager, JsonNetTests", "Reports": [ { "$id": "2", "$type": "JsonNetTests.Employee, JsonNetTests", "Name": "User1" }, { "$id": "3", "$type": "JsonNetTests.Manager, JsonNetTests", "Reports": [ { "$ref": "2" } ], "Name": "User3" } ], "Name": "User2" }
public class User { public int Id { set; get; } [JsonIgnore] public string Name { set; get; } public DateTime DateTime { set; get; } }
[JsonProperty(PropertyName = "m_name", NullValueHandling = NullValueHandling.Ignore)] public string Name { set; get; }
[JsonObject(MemberSerialization.OptIn)] public class User { public int Id { set; get; } [JsonProperty] public string Name { set; get; } public DateTime DateTime { set; get; } }
[JsonConverter(typeof(JavaScriptDateTimeConverter))] public DateTime DateTime { set; get; }
public class HtmlColor { public int Red { set; get; } public int Green { set; get; } public int Blue { set; get; } } var colorJson = JsonConvert.SerializeObject(new HtmlColor { Red = 255, Green = 0, Blue = 0 }, Formatting.Indented);
public class HtmlColorConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(HtmlColor); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotSupportedException(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var color = value as HtmlColor; if (color == null) return; writer.WriteValue("#" + color.Red.ToString("X2") + color.Green.ToString("X2") + color.Blue.ToString("X2")); } }
var colorJson = JsonConvert.SerializeObject(new HtmlColor { Red = 255, Green = 0, Blue = 0 }, new JsonSerializerSettings { Formatting = Formatting.Indented, Converters = { new HtmlColorConverter() } });
استفاده از Exception برای نمایش پیغام برای کاربر نهایی
با صدور یک استثناء و مدیریت سراسری آن در بالاترین (خارجی ترین) لایه و نمایش پیغام مرتبط با آن به کاربر نهایی، میتوان از آن به عنوان ابزاری برای ارسال هر نوع پیغامی به کاربر نهایی استفاده کرد. اگر قوانین تجاری با موفقیت برآورده نشدهاند یا لازم است به هر دلیلی یک پیغام مرتبط با یک اعتبارسنجی تجاری را برای کاربر نمایش دهید، این روش بسیار کارساز میباشد و با یکبار وقت گذاشتن برای توسعه زیرساخت برای این موضوع، به عنوان یک Cross Cutting Concern تحت عنوان Exception Management، آزادی عمل زیادی در ادامه توسعه سیستم خود خواهید داشت.
اگر مطالب پیش نیاز را مطالعه کنید، قطعا روش مطرح شده را انتخاب نخواهید کرد؛ به همین دلیل به دنبال راه حل صحیح برخورد با این سناریوها بودم که نتیجه آن را در ادامه خواهیم دید.
راه حل صحیح برای برخورد با این سناریوها بازگشت یک Result میباشد که در مطلب قبلی هم تحت عنوان OperationResult مطرح شد.
public class Result { private static readonly Result SuccessResult = new Result(true, null); protected Result(bool succeeded, string message) { if (succeeded) { if (message != null) throw new ArgumentException("There should be no error message for success.", nameof(message)); } else { if (message == null) throw new ArgumentNullException(nameof(message), "There must be error message for failure."); } Succeeded = succeeded; Error = message; } public bool Succeeded { get; } public string Error { get; } [DebuggerStepThrough] public static Result Success() { return SuccessResult; } [DebuggerStepThrough] public static Result Failed(string message) { return new Result(false, message); } [DebuggerStepThrough] public static Result<T> Failed<T>(string message) { return new Result<T>(default, false, message); } [DebuggerStepThrough] public static Result<T> Success<T>(T value) { return new Result<T>(value, true, string.Empty); } [DebuggerStepThrough] public static Result Combine(string seperator, params Result[] results) { var failedResults = results.Where(x => !x.Succeeded).ToList(); if (!failedResults.Any()) return Success(); var error = string.Join(seperator, failedResults.Select(x => x.Error).ToArray()); return Failed(error); } [DebuggerStepThrough] public static Result Combine(params Result[] results) { return Combine(", ", results); } [DebuggerStepThrough] public static Result Combine<T>(params Result<T>[] results) { return Combine(", ", results); } [DebuggerStepThrough] public static Result Combine<T>(string seperator, params Result<T>[] results) { var untyped = results.Select(result => (Result) result).ToArray(); return Combine(seperator, untyped); } public override string ToString() { return Succeeded ? "Succeeded" : $"Failed : {Error}"; } }
مشابه کلاس بالا، در فریمورک ASP.NET Identity کلاسی تحت عنوان IdentityResult برای همین منظور در نظر گرفته شدهاست.
پراپرتی Succeeded نشان دهنده موفقت آمیز بودن یا عدم موفقیت عملیات (به عنوان مثال یک متد ApplicationService) میباشد. پراپرتی Error دربرگیرنده پیغام خطایی میباشد که قبلا از طریق Message مربوط به یک استثناء صادر شده، در اختیار بالاترین لایه قرار میگرفت. با استفاده از متد Combine، امکان ترکیب چندین Result حاصل از عملیات مختلف را خواهید داشت. متدهای استاتیک Failed و Success هم برای درگیر نشدن برای وهله سازی از کلاس Result در نظر گرفته شدهاند.
متد GetForEdit مربوط به MeetingService را در نظر بگیرید. به عنوان مثال وظیفه این متد بازگشت یک MeetingEditModel میباشد؛ اما با توجه به یکسری قواعد تجاری، بهعنوان مثال «امکان ویرایش جلسهای که پابلیش نهایی شدهاست، وجود ندارد و ...» لازم است خروجی این متد نیز در صورت Fail شدن، دلیل آن را به مصرف کننده ارائه دهد. از این رو کلاس جنریک Result را به شکل زیر خواهیم داشت:
public class Result<T> : Result { private readonly T _value; protected internal Result(T value, bool succeeded, string error) : base(succeeded, error) { _value = value; } public T Value { get { if (!Succeeded) throw new InvalidOperationException("There is no value for failure."); return _value; } } }
public static class ResultExtensions { public static Result<TK> OnSuccess<T, TK>(this Result<T> result, Func<T, TK> func) { return !result.Succeeded ? Result.Failed<TK>(result.Error) : Result.Success(func(result.Value)); } public static Result<T> Ensure<T>(this Result<T> result, Func<T, bool> predicate, string message) { if (!result.Succeeded) return Result.Failed<T>(result.Error); return !predicate(result.Value) ? Result.Failed<T>(message) : Result.Success(result.Value); } public static Result<TK> Map<T, TK>(this Result<T> result, Func<T, TK> func) { return !result.Succeeded ? Result.Failed<TK>(result.Error) : Result.Success(func(result.Value)); } public static Result<T> OnSuccess<T>(this Result<T> result, Action<T> action) { if (result.Succeeded) action(result.Value); return result; } public static T OnBoth<T>(this Result result, Func<Result, T> func) { return func(result); } public static Result OnSuccess(this Result result, Action action) { if (result.Succeeded) action(); return result; } public static Result<T> OnSuccess<T>(this Result result, Func<T> func) { return !result.Succeeded ? Result.Failed<T>(result.Error) : Result.Success(func()); } public static Result<TK> OnSuccess<T, TK>(this Result<T> result, Func<T, Result<TK>> func) { return !result.Succeeded ? Result.Failed<TK>(result.Error) : func(result.Value); } public static Result<T> OnSuccess<T>(this Result result, Func<Result<T>> func) { return !result.Succeeded ? Result.Failed<T>(result.Error) : func(); } public static Result<TK> OnSuccess<T, TK>(this Result<T> result, Func<Result<TK>> func) { return !result.Succeeded ? Result.Failed<TK>(result.Error) : func(); } public static Result OnSuccess<T>(this Result<T> result, Func<T, Result> func) { return !result.Succeeded ? Result.Failed(result.Error) : func(result.Value); } public static Result OnSuccess(this Result result, Func<Result> func) { return !result.Succeeded ? result : func(); } public static Result Ensure(this Result result, Func<bool> predicate, string message) { if (!result.Succeeded) return Result.Failed(result.Error); return !predicate() ? Result.Failed(message) : Result.Success(); } public static Result<T> Map<T>(this Result result, Func<T> func) { return !result.Succeeded ? Result.Failed<T>(result.Error) : Result.Success(func()); } public static TK OnBoth<T, TK>(this Result<T> result, Func<Result<T>, TK> func) { return func(result); } public static Result<T> OnFailure<T>(this Result<T> result, Action action) { if (!result.Succeeded) action(); return result; } public static Result OnFailure(this Result result, Action action) { if (!result.Succeeded) action(); return result; } public static Result<T> OnFailure<T>(this Result<T> result, Action<string> action) { if (!result.Succeeded) action(result.Error); return result; } public static Result OnFailure(this Result result, Action<string> action) { if (!result.Succeeded) action(result.Error); return result; } }
[HttpPost, AjaxOnly, ValidateAntiForgeryToken, ValidateModelState] public virtual async Task<ActionResult> Create([Bind(Prefix = "Model")]MeetingCreateModel model) { var result = await _service.CreateAsync(model); return result.OnSuccess(() => { }) .OnFailure(() => { }) .OnBoth(r => r.Succeeded ? InformationNotification("Messages.Save.Success") : ErrorMessage(r.Error)); }
یا در حالتهای پیچیده تر:
var result = await _service.CreateAsync(new TenantAwareEntityCreateModel()); return Result.Combine(result, Result.Success(), Result.Failed("نتیجه یک متد دیگر به عنوان مثال")) .OnSuccess(() => { }) .OnFailure(() => { }) .OnBoth(r => r.Succeeded ? Json("OK") : Json(r.Error));
ترکیب با الگوی Maybe یا Option
public struct Maybe<T> : IEquatable<Maybe<T>> where T : class { private readonly T _value; private Maybe(T value) { _value = value; } public bool HasValue => _value != null; public T Value => _value ?? throw new InvalidOperationException(); public static Maybe<T> None => new Maybe<T>(); public static implicit operator Maybe<T>(T value) { return new Maybe<T>(value); } public static bool operator ==(Maybe<T> maybe, T value) { return maybe.HasValue && maybe.Value.Equals(value); } public static bool operator !=(Maybe<T> maybe, T value) { return !(maybe == value); } public static bool operator ==(Maybe<T> left, Maybe<T> right) { return left.Equals(right); } public static bool operator !=(Maybe<T> left, Maybe<T> right) { return !(left == right); } /// <inheritdoc /> /// <summary> /// Avoid boxing and Give type safety /// </summary> /// <param name="other"></param> /// <returns></returns> public bool Equals(Maybe<T> other) { if (!HasValue && !other.HasValue) return true; if (!HasValue || !other.HasValue) return false; return _value.Equals(other.Value); } /// <summary> /// Avoid reflection /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { if (obj is T typed) { obj = new Maybe<T>(typed); } if (!(obj is Maybe<T> other)) return false; return Equals(other); } /// <summary> /// Good practice when overriding Equals method. /// If x.Equals(y) then we must have x.GetHashCode()==y.GetHashCode() /// </summary> /// <returns></returns> public override int GetHashCode() { return HasValue ? _value.GetHashCode() : 0; } public override string ToString() { return HasValue ? _value.ToString() : "NO VALUE"; } }
public static Result<T> ToResult<T>(this Maybe<T> maybe, string message) where T : class { return !maybe.HasValue ? Result.Failed<T>(message) : Result.Success(maybe.Value); }
Result<Customer> customerResult = _customerRepository.GetById(model.Id) .ToResult("Customer with such Id is not found: " + model.Id);
همچنین متدهای الحاقی زیر را نیز برای ساختار داده Maybe میتوان در نظر گرفت:
public static T GetValueOrDefault<T>(this Maybe<T> maybe, T defaultValue = default) where T : class { return maybe.GetValueOrDefault(x => x, defaultValue); } public static TK GetValueOrDefault<T, TK>(this Maybe<T> maybe, Func<T, TK> selector, TK defaultValue = default) where T : class { return maybe.HasValue ? selector(maybe.Value) : defaultValue; } public static Maybe<T> Where<T>(this Maybe<T> maybe, Func<T, bool> predicate) where T : class { if (!maybe.HasValue) return default(T); return predicate(maybe.Value) ? maybe : default(T); } public static Maybe<TK> Select<T, TK>(this Maybe<T> maybe, Func<T, TK> selector) where T : class where TK : class { return !maybe.HasValue ? default : selector(maybe.Value); } public static Maybe<TK> Select<T, TK>(this Maybe<T> maybe, Func<T, Maybe<TK>> selector) where T : class where TK : class { return !maybe.HasValue ? default(TK) : selector(maybe.Value); } public static void Execute<T>(this Maybe<T> maybe, Action<T> action) where T : class { if (!maybe.HasValue) return; action(maybe.Value); } }
using System;
using System.IO;
using System.Web;
using System.Web.Services;
using System.Reflection;
namespace test1
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class cache : IHttpHandler
{
private static void cacheIt(TimeSpan duration)
{
HttpCachePolicy cache = HttpContext.Current.Response.Cache;
FieldInfo maxAgeField = cache.GetType().GetField("_maxAge", BindingFlags.Instance | BindingFlags.NonPublic);
maxAgeField.SetValue(cache, duration);
cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(DateTime.Now.Add(duration));
cache.SetMaxAge(duration);
cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
}
public void ProcessRequest(HttpContext context)
{
string file = context.Request.QueryString["file"];
if (string.IsNullOrEmpty(file))
{
return;
}
string contetType = context.Request.QueryString["contetType"];
if (string.IsNullOrEmpty(contetType))
{
return;
}
context.Response.Write(File.ReadAllText(context.Server.MapPath(file)));
//Set the content type
context.Response.ContentType = contetType;
// Cache the resource for 30 Days
cacheIt(TimeSpan.FromDays(30));
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
<link type="text/css" href="cache.ashx?v=1&file=site.css&contetType=text/css" rel="Stylesheet" />
<script type="text/javascript" src="cache.ashx?v=1&file=js/jquery-1.3.2.min.js&contetType=application/x-javascript"></script>
<h3>Angular Forms</h3> <form #form="ngForm"> <input type="text" placeholder="Name"> <button type="submit">Ok</button> </form> form.pristine: {{ form.pristine }}
There is no directive with "exportAs" set to "ngForm"
<h3>Angular Forms</h3> <form #form="ngForm"> <input type="text" placeholder="Name" name="name" ngModel> <button type="submit">Ok</button> </form> form.pristine: {{ form.pristine }}
Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.
<input type="text" required placeholder="Name" name="name" ngModel>
<form #form="ngForm" novalidate>
<div class="container"> <h3>Angular Forms</h3> <form #form="ngForm" novalidate> <div class="form-group"> <label>First Name</label> <input type="text" class="form-control" required name="firstName" ngModel> </div> <div class="form-group"> <label>Last Name</label> <input type="text" class="form-control" required name="lastName" ngModel> </div> <button class="btn btn-primary" type="submit">Ok</button> </form> </div> form.pristine: {{ form.pristine }}
<div class="checkbox"> <label> <input type="checkbox" name="is-full-time" ngModel> Full Time Employee </label> </div>
<label>Payment Type</label> <div class="radio"> <label> <input type="radio" name="pay-type" value="FullTime" checked> Full Time </label> </div> <div class="radio"> <label> <input type="radio" name="pay-type" value="PartTime"> Part Time </label> </div>
<div class="form-group"> <label>Primary Language</label> <select class="form-control"> <option *ngFor="let lang of languages"> {{ lang }} </option> </select> </div>
export class EmployeeRegisterComponent implements OnInit { languages = ["Persian", "English", "Spanish", "Other"];
<select class="form-control"> <option>Persian</option> <option>English</option> <option>Spanish</option> <option>Other</option> </select>