نظرات مطالب
نحوه استفاده از ViewModel در ASP.NET MVC
در قسمت «تزریق نواحی ویژه یک View در فایل layout» به این موضوع پرداخته شده.
در سری اولی که تهیه کردم یک واژه بود که به این صورت تلفظ میکرد: «لَت». در قسمت دوم متوجه شدم که منظورش همان «layout» است!
وبلاگش اینجا است: (^)
وبلاگش اینجا است: (^)
یک نکتهی تکمیلی: جایگزین کردن if/elseهای بررسی نال بودن با یک کامپوننت
در کدهای Razor، داشتن چنین قطعه کدی بسیار مرسوم هست:
@if(someValue is null) { <p>Loading..</p> } else { // show actual content } @code { SomeClass someValue; }
/* shows a loading gif/text if a value is null */ @if (Value == null) { <div><img src="/img/SmallLoader.gif" alt="loading" /> Loading</div> } else { @ChildContent } @code { [Parameter] public RenderFragment ChildContent { get; set; } [Parameter] public object Value { get; set; } }
<Loading Value="someValue"> <p>Content goes here</p> </Loading>
در مطلب «Angular CLI - قسمت پنجم - ساخت و توزیع برنامه» با نحوهی ساخت و توزیع برنامههای Angular، در دو حالت محیط توسعه و محیط ارائهی نهایی آشنا شدیم. همچنین در مطلب «یکپارچه سازی Angular CLI و ASP.NET Core در VS 2017» نحوهی ترکیب یک برنامهی ASP.NET Core و Angular را بررسی کردیم. در اینجا میخواهیم فایل index.html ایی را که Angular CLI تولید میکند، با فایل Layout برنامههای ASP.NET Core جایگزین کنیم؛ تا بتوانیم در صورت نیاز، سفارشی سازیهای بیشتری را به صفحهی اول سایت اعمال نمائیم.
استفاده از Tag Helpers ویژهی ASP.NET Core برای مدیریت محیطهای توسعه و تولید
فایلهای برنامهی تک صفحهای تولید شدهی توسط Angular CLI، در نهایت یک چنین شکلی را خواهند داشت:
این فایلها نیز در حالت توسعه تهیه شدهاند. در یک برنامهی واقعی، صفحهی سادهی index.html تولیدی آن، تنها میتواند یک قالب شروع به کار باشد و نه فایل نهایی که قرار است ارائه شود. نیاز است به این فایل تگهای بیشتری را اضافه کرد و سفارشی سازیهای خاصی را به آن اعمال نمود. در این حالت با توجه به بازنویسی و تولید مجدد این فایل در هر بار ساخت برنامه، میتوان از فایل Layout پروژهی ASP.NET Core جاری استفاده کرد. به این ترتیب از مزایای Razor و تمام زیرساختی که در اختیار داریم نیز محروم نخواهیم شد.
بنابراین تنها کاری را که باید انجام دهیم، کپی ساختار فایل index.html تولیدی به فایل Layout برنامه است.
مشکل! در حالت توسعه، نام فایلهای تولید شده به همین سادگی است که ملاحظه میکنید. اما در حالت ارائهی نهایی، این فایلها به همراه یک هش نیز تولید میشوند (پیاده سازی مفهوم cache busting و اجبار به بهروز رسانی کش مرورگر، باتوجه به تغییر آدرس فایلها)؛ مانند vendor.ea3f8329096dbf5632af.bundle.js
راه حل اول: تولید فایلهای نهایی بدون هش
در حین ساخت و تولید یک برنامهی Angular CLI در حالت ارائهی نهایی، تنها کافی است سوئیچ output-hashing، به none تنظیم شود، تا این هشها به نام فایلهای تولیدی اضافه نشوند.
درکل بهتر است از این روش استفاده نشود، چون با وجود پروکسیهای کش کردن اطلاعات در بین راه، احتمال اینکه کاربران نگارشهای قدیمی برنامه را مشاهده کنند، بسیار زیاد است.
راه حل دوم: تگ Script در ASP.NET Core اجازهی ذکر تمام فایلهای اسکریپت یک پوشه را نیز میدهد
هرچند این قابلیت جالب است و سبب الحاق یکجای تمام فایلهای js موجود در پوشهی wwwroot خواهد شد، اما پاسخگوی کار ما نخواهد بود؛ چون ترتیب قرارگیری این فایلها مهم است.
راه حل واقعی
در اینجا کدهای کامل فایل Views\Shared\_Layout.cshtml را که میتواند جایگزین فایل index.html تولیدی توسط Angular CLI باشد، ملاحظه میکنید:
در اینجا دو حالت توسعه و همچنین ارائهی نهایی مدنظر قرار گرفتهاند. در حالت توسعه، دقیقا از همان نامهای سادهی تولیدی استفاده شدهاست و در حالت ارائهی نهایی چون نام فایلها به صورت
تولید میشوند، میتوان قسمت هش را با * جایگزین کرد؛ مانند "asp-src-include="~/vendor*.js
همچنین باید دقت داشت که در حالت توسعه، تمام شیوه نامههای برنامه در فایل styles.bundle.js قرار میگیرند. اما در حالت ارائهی نهایی، این فایل وجود نداشته و با نام کلی styles*.css تولید میشود که باید در head صفحه قرار گیرد (مانند تنظیمات حالت تولید در Layout فوق).
اصلاح قسمت URL Rewrite برنامه
در حالت کار با برنامههای تک صفحهای وب، در اولین درخواست رسیدهی به برنامه ممکن است آدرسی درخواست شود که معادل کنترلر و اکشن متدی را در برنامهی سمت سرور نداشته باشد. در این حالت کاربر را به همان صفحهی index.html هدایت میکنیم تا سیستم مسیریابی سمت کلاینت، کار نمایش آن صفحه را انجام دهد:
از آنجائیکه پس از اصلاحات فوق دیگر از این فایل استفاده نمیشود، باید تغییر ذیل را نیز اعمال کرد:
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.
استفاده از Tag Helpers ویژهی ASP.NET Core برای مدیریت محیطهای توسعه و تولید
فایلهای برنامهی تک صفحهای تولید شدهی توسط Angular CLI، در نهایت یک چنین شکلی را خواهند داشت:
این فایلها نیز در حالت توسعه تهیه شدهاند. در یک برنامهی واقعی، صفحهی سادهی index.html تولیدی آن، تنها میتواند یک قالب شروع به کار باشد و نه فایل نهایی که قرار است ارائه شود. نیاز است به این فایل تگهای بیشتری را اضافه کرد و سفارشی سازیهای خاصی را به آن اعمال نمود. در این حالت با توجه به بازنویسی و تولید مجدد این فایل در هر بار ساخت برنامه، میتوان از فایل Layout پروژهی ASP.NET Core جاری استفاده کرد. به این ترتیب از مزایای Razor و تمام زیرساختی که در اختیار داریم نیز محروم نخواهیم شد.
بنابراین تنها کاری را که باید انجام دهیم، کپی ساختار فایل index.html تولیدی به فایل Layout برنامه است.
مشکل! در حالت توسعه، نام فایلهای تولید شده به همین سادگی است که ملاحظه میکنید. اما در حالت ارائهی نهایی، این فایلها به همراه یک هش نیز تولید میشوند (پیاده سازی مفهوم cache busting و اجبار به بهروز رسانی کش مرورگر، باتوجه به تغییر آدرس فایلها)؛ مانند vendor.ea3f8329096dbf5632af.bundle.js
راه حل اول: تولید فایلهای نهایی بدون هش
ng build -prod --output-hashing=none
درکل بهتر است از این روش استفاده نشود، چون با وجود پروکسیهای کش کردن اطلاعات در بین راه، احتمال اینکه کاربران نگارشهای قدیمی برنامه را مشاهده کنند، بسیار زیاد است.
راه حل دوم: تگ Script در ASP.NET Core اجازهی ذکر تمام فایلهای اسکریپت یک پوشه را نیز میدهد
<script type="text/javascript" asp-src-include="*.js"></script>
راه حل واقعی
در اینجا کدهای کامل فایل Views\Shared\_Layout.cshtml را که میتواند جایگزین فایل index.html تولیدی توسط Angular CLI باشد، ملاحظه میکنید:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="icon" type="image/x-icon" href="favicon.ico"> <title>ng2-lab</title> <base href="/"> <environment names="Development"> </environment> <environment names="Staging,Production"> <link rel="stylesheet" asp-href-include="~/styles*.css" /> </environment> </head> <body> @RenderBody() <app-root></app-root> <environment names="Development"> <script type="text/javascript" src="/inline.bundle.js"></script> <script type="text/javascript" src="/polyfills.bundle.js"></script> <script type="text/javascript" src="/scripts.bundle.js"></script> <script type="text/javascript" src="/styles.bundle.js"></script> <script type="text/javascript" src="/vendor.bundle.js"></script> <script type="text/javascript" src="/main.bundle.js"></script> </environment> <environment names="Production,Staging"> <script type="text/javascript" asp-src-include="~/inline*.js"></script> <script type="text/javascript" asp-src-include="~/polyfills*.js"></script> <script type="text/javascript" asp-src-include="~/scripts*.js"></script> <script type="text/javascript" asp-src-include="~/vendor*.js"></script> <script type="text/javascript" asp-src-include="~/main*.js"></script> </environment> </body> </html>
[name].[hash].bundle.js
همچنین باید دقت داشت که در حالت توسعه، تمام شیوه نامههای برنامه در فایل styles.bundle.js قرار میگیرند. اما در حالت ارائهی نهایی، این فایل وجود نداشته و با نام کلی styles*.css تولید میشود که باید در head صفحه قرار گیرد (مانند تنظیمات حالت تولید در Layout فوق).
اصلاح قسمت URL Rewrite برنامه
در حالت کار با برنامههای تک صفحهای وب، در اولین درخواست رسیدهی به برنامه ممکن است آدرسی درخواست شود که معادل کنترلر و اکشن متدی را در برنامهی سمت سرور نداشته باشد. در این حالت کاربر را به همان صفحهی index.html هدایت میکنیم تا سیستم مسیریابی سمت کلاینت، کار نمایش آن صفحه را انجام دهد:
app.Use(async (context, next) => { await next(); var path = context.Request.Path.Value; if (path != null && context.Response.StatusCode == 404 && !Path.HasExtension(path) && !path.StartsWith("/api/", StringComparison.OrdinalIgnoreCase)) { context.Request.Path = "/index.html"; await next(); } });
//context.Request.Path = "/index.html"; context.Request.Path = "/"; // since we are using views/shared/_layout.cshtml now.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.
برخی اوقات نیاز است در یک فرم ویندوزی، کنترلهای آنرا در حال اجرا با استفاده از ماوس جابجا کنیم و یا اندازهی آنها را تغییر بدیم.
در وب راهکارهای مختلفی برای این کار ارائه شده، ولی این راهها معمولا یا فقط برای تغییر مکان و یا فقط برای تغییر اندازه کنترلها ارائه شدهاند. من یکی از مقالات کد پروجکت را که به جابجا کردن کنترلها پرداخته بود، توسعه دادم که امکان تغییر اندازه هم به آن اضافه شود. مقالهی من (به زبان انگلیسی) در اینجا قرار دارد.
چون از کلاس و متدهای استاتیک استفاده کردم، روش استفاده از این کلاس ساده بوده و افزودن قابلیت تغییر اندازه و جابجایی زمان اجرا با ماوس برای هر کنترل فقط با یک خط کد قابل انجام است:
نحوهی استفاده از کلاس:
برای فعال کردن قابلیت تغییر اندازه و جابجایی یک کنترل در حال اجرای برنامه با موس ما باید متد Init از کلاس MoveAndResizeControls را فراخوانی کنیم و کنترل را به عنوان پارامتر به آن بفرستیم.
اگر که ما بخواهیم به همراه تغییر کنترل ، خواص container آن را هم تغییر دهیم. باید کنترل container را به عنوان پارامتر دوم به متد مذکور ارسال کنیم.
برخی اوقات ممکن است که ما فقط بخواهیم که یا کنترلها را جابجا کنیم و یا اندازهی آنها را تغییر دهیم؛ در این مواقع ما باید خاصیت WorkType کلاس MoveAndResizeControls را تغییر دهیم به یکی از مقادیر ذیل تغییر دهیم .
مثالی از نحوهی کار با کلاس :
نکته :بعد از انجام تغییرات، جهت ذخیره وضعیت کنترلها و بازیابی مجدد آنها میتوان از متدهای زیر استفاده کرد:
در وب راهکارهای مختلفی برای این کار ارائه شده، ولی این راهها معمولا یا فقط برای تغییر مکان و یا فقط برای تغییر اندازه کنترلها ارائه شدهاند. من یکی از مقالات کد پروجکت را که به جابجا کردن کنترلها پرداخته بود، توسعه دادم که امکان تغییر اندازه هم به آن اضافه شود. مقالهی من (به زبان انگلیسی) در اینجا قرار دارد.
چون از کلاس و متدهای استاتیک استفاده کردم، روش استفاده از این کلاس ساده بوده و افزودن قابلیت تغییر اندازه و جابجایی زمان اجرا با ماوس برای هر کنترل فقط با یک خط کد قابل انجام است:
ControlMoverOrResizer.Init(button1);
برای فعال کردن قابلیت تغییر اندازه و جابجایی یک کنترل در حال اجرای برنامه با موس ما باید متد Init از کلاس MoveAndResizeControls را فراخوانی کنیم و کنترل را به عنوان پارامتر به آن بفرستیم.
ControlMoverOrResizer.Init(button1);
ControlMoverOrResizer.Init(button2,panel1);
internal enum MoveOrResize { Move, Resize, MoveAndResize }
مثالی از نحوهی کار با کلاس :
using System; using System.Windows.Forms; using ControlManager; namespace MoveAndResizeControls { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { ControlMoverOrResizer.Init(button1); ControlMoverOrResizer.Init(groupBox1); ControlMoverOrResizer.Init(textBox1); ControlMoverOrResizer.Init(button2,panel1); comboBox1.SelectedIndex = 0; } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { switch (comboBox1.SelectedIndex) { case 0: ControlMoverOrResizer.WorkType=ControlMoverOrResizer.MoveOrResize.MoveAndResize; break; case 1: ControlMoverOrResizer.WorkType = ControlMoverOrResizer.MoveOrResize.Move; break; case 2: ControlMoverOrResizer.WorkType = ControlMoverOrResizer.MoveOrResize.Resize; break; } } } }
نکته :بعد از انجام تغییرات، جهت ذخیره وضعیت کنترلها و بازیابی مجدد آنها میتوان از متدهای زیر استفاده کرد:
GetSizeAndPositionOfControlsToString , SetSizeAndPositionOfControlsFromString
شکل حالت نتیجه:
با سلام.
امکان مرتب سازی یک table با این کامپوننت وجود دارد؟
سعی من بی نتیجه بود. با تشکر.
نظرات مطالب
لیست تازههای IIS 7.5
IIS یک کامپوننت ویندوز است و جدا از ویندوز ارائه نمیشود.
اشتراکها
کتابخانه ngx-page-scroll
Animated scrolling functionality for angular written in pure typescript with no additional dependencies Demo
- easy-to-use directive: scroll to an element referenced in the href-attribute (
href="#mytarget
) just by addingpageScroll
directive - service usage: trigger scroll animations from your component or when server responds
- customizable: adjust duration, offset or whether scrolling stops if the user interrupts (read more)
- use custom easing functions to calculate the scroll position over time
- works across routes (scrolls to target element as soon as the routing has finished) and in both directions (horizontal/vertical)
npm install ngx-page-scroll