برنامه Angular IDE
آشنایی با امکانات بستهی angular/platform-browser@
در ماژول angular/platform-browser@، دو سرویس Meta و Title، امکان تغییر پویای متاتگهای صفحهی جاری را مهیا میکنند. برای نمونه فرض کنید قصد دارید یک چنین متاتگهایی را به صفحهی جاری اضافه کنید:
<head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <title>newTitle ...</title> <base href="/"> <meta name="description" content="Angular meta service"> <meta name="author" content="DNT"> <meta name="keywords" content="Angular, Meta Service"> <meta name="twitter:card" content="summary"> <meta name="twitter:site" content="@my_site"> <meta name="twitter:title" content="Front-end Web Development"> <meta name="twitter:description" content="Learn frontend web development..."> <meta name="twitter:image" content="https://site/images/image.png"> <meta name="author" content="Other Author"> </head>
import { Component, OnInit } from "@angular/core"; import { Meta, Title } from "@angular/platform-browser"; @Component({ selector: "app-seo-tests", templateUrl: "./seo-tests.component.html", styleUrls: ["./seo-tests.component.css"] }) export class SeoTestsComponent implements OnInit { constructor(private metaService: Meta, private titleService: Title) { }
افزودن یک یا چند متاتگ
متد addTag سرویس Meta، کار افزودن پویای یک متا تگ جدید را به همراه ویژگیهای name و content آن، انجام میدهد. در ذیل چندین مثال از آنرا مشاهده میکنید. در اینجا یا میتوان از متد addTag استفاده کرد که تنها یک متاتگ را به صفحه اضافه میکند و یا از متد addTags کمک گرفت که میتواند آرایهای از متاتگها را به صورت پویا به صفحهی جاری اضافه کند:
// addTag & addTags this.metaService.addTag({ name: "description", content: "How to optimize your Angular App for search engine and other crawlers." }); this.metaService.addTag({ name: "author", content: "DNT" }); this.metaService.addTag({ name: "keywords", content: "Angular, Meta Service" }); // Or this.metaService.addTags([ { name: "description", content: "How to optimize your Angular App for search engine and other crawlers." }, { name: "author", content: "DNT" }, { name: "keywords", content: "Angular, Meta Service" } ], false); // --> forceCreation = false this.metaService.addTag({ name: "twitter:card", content: "summary_large_image" }); this.metaService.addTag({ name: "twitter:site", content: "@my_site" }); this.metaService.addTag({ name: "twitter:title", content: "Front-end Web Development" }); this.metaService.addTag({ name: "twitter:description", content: "Learn frontend web development..." }); this.metaService.addTag({ name: "twitter:image", content: "https://site/images/image.png" }); // Or this.metaService.addTags([ { name: "twitter:card", content: "summary_large_image" }, { name: "twitter:site", content: "@my_site" }, ], false); // --> forceCreation = false
دریافت محتوای متاتگهای موجود
با استفاده از متد getTag میتوان یک متاتگ مشخص را به صورت HTMLMetaElement دریافت کرد:
// getTag & getTags const viewport = this.metaService.getTag("name=viewport"); if (viewport) { console.log(viewport.content); // width=device-width, initial-scale=1 } const author = this.metaService.getTag("name=author"); if (author) { console.log(author.content); // DNT } this.metaService.addTag({ name: "author", content: "DNT" }); this.metaService.addTag({ name: "author", content: "Other Author" }, true); const authors = this.metaService.getTags("name=author"); console.log(authors[0]); // <meta name="author" content="DNT"> console.log(authors[1]); // <meta name="author" content="Other Author">
به روز رسانی متاتگهای موجود
میتوان از متد updateTag برای تغییر محتوای متاتگی موجود، استفاده کرد:
// updateTag this.metaService.addTag({ name: "twitter:card", content: "summary_large_image" }); this.metaService.updateTag({ name: "twitter:card", content: "summary" }, `name='twitter:card'`); this.metaService.updateTag({ name: "description", content: "Angular meta service" });
حذف تگهای موجود
در اینجا میتوان از دو متد removeTag که یک attribute-selector را دریافت میکند و یا removeTagElement که یک HTMLMetaElement را توسط متد getTag دریافت میکند، برای حذف کامل این تگها استفاده کرد:
// removeTag & removeTagElement this.metaService.removeTag("charset"); // Or const chartsetTag = this.metaService.getTag("charset"); if (chartsetTag) { this.metaService.removeTagElement(chartsetTag); }
تنظیم عنوان صفحهی جاری
سرویس توکار دیگری به نام Title امکان تغییر عنوان صفحهی جاری را به صورت پویا میسر میکند:
// Setting the browser page Title in an Angular app const currentTitle = this.titleService.getTitle(); console.log(currentTitle); this.titleService.setTitle("newTitle ...");
طراحی سرویسی برای افزودن پویای متاتگها به صفحات مختلف سایت
میتوان شبیه به مطلب «نمایش Breadcrumbs در برنامههای Angular» به قسمت data مسیریابی، اطلاعات عنوان صفحه و همچنین metaTags آنرا اضافه کرد:
const routes: Routes = [ { path: "seo", component: SeoTestsComponent, data: { title: "Page Title", metaTags: { description: "Page Description or some content here", keywords: "some, keywords, here, separated, by, a comma" } } } ];
به همین جهت سرویس SEO را در مسیر src\app\core\seo-service.ts به صورت ذیل ایجاد میکنیم:
import { Injectable } from "@angular/core"; import { Title, Meta } from "@angular/platform-browser"; import { Router, NavigationEnd, ActivatedRouteSnapshot } from "@angular/router"; @Injectable() export class SeoService { constructor(private titleService: Title, private metaService: Meta, private router: Router) { } enableSeo() { this.router.events .filter(event => event instanceof NavigationEnd) .distinctUntilChanged() .subscribe(() => { this.addMetaData(this.router.routerState.snapshot.root); }); } private addMetaData(root: ActivatedRouteSnapshot): void { if (root.children && root.children.length) { this.addMetaData(root.children[0]); } else if (root.data) { this.setTitle(root.data); this.setMetaTags(root.data); } } private setMetaTags(routeData: { [name: string]: any; }) { const routeDataMetaTagsKey = "metaTags"; const metaTags = routeData[routeDataMetaTagsKey]; if (!metaTags) { return; } for (const tag in metaTags) { if (metaTags.hasOwnProperty(tag)) { const newTag = { name: tag, content: metaTags[tag] }; console.log("new tag", newTag); this.metaService.addTag(newTag); } } } private setTitle(routeData: { [name: string]: any; }) { const routeDataTitleKey = "title"; const title = routeData[routeDataTitleKey]; if (title) { console.log("new title", title); this.titleService.setTitle(title); } } }
در اینجا در ابتدای کار مشترک رخداد NavigationEnd سیستم مسیریابی خواهیم شد:
this.router.events .filter(event => event instanceof NavigationEnd) .distinctUntilChanged() .subscribe(() => { this.addMetaData(this.router.routerState.snapshot.root); });
سپس در این متد خاصیت data مسیرنهایی را خوانده و کلیدهای title و metaTags آنرا استخراج میکنیم و سپس توسط متدهای this.titleService.setTitle و this.metaService.addTag، این عنوان و متاتگهای جدید را به صورت پویا به صفحه اضافه خواهیم کرد.
پس از تعریف این سرویس، برای معرفی آن به برنامه، ابتدا آنرا به قسمت providers مربوط به CoreModule اضافه میکنیم:
import { SeoService } from "./seo-service"; @NgModule({ providers: [ SeoService ] }) export class CoreModule {}
import { SeoService } from "./core/seo-service"; export class AppComponent { constructor(private seoService: SeoService) { this.seoService.enableSeo(); } }
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.
دیباگ بهتر توسط کدهای مرجع دات نت
سری آموزشی Blazor Hybrid
Blazor Hybrid for Beginners
Join James Montemagno as he takes you on a journey of building your first Hybrid applications across iOS, Android, Mac, Windows, and Web with ASP.NET Core, Blazor, Blazor Hybrid, and .NET MAUI! You will learn how to use Blazor Hybrid to blend desktop and mobile native client frameworks with .NET and Blazor.
In a Blazor Hybrid app, Razor components run natively on the device. Components render to an embedded Web View control through a local interop channel. Components don't run in the browser, and WebAssembly isn't involved. Razor components load and execute code quickly, and components have full access to the native capabilities of the device through the .NET platform. Component styles rendered in a Web View are platform dependent and may require you to account for rendering differences across platforms using custom stylesheets.
Blazor Hybrid support is built into the .NET Multi-platform App UI (.NET MAUI) framework. .NET MAUI includes the BlazorWebView control that permits rendering Razor components into an embedded Web View. By using .NET MAUI and Blazor together, you can reuse one set of web UI components across mobile, desktop, and web.
Why Serilog? It is easy to set up, has a clean API, and is portable between recent .NET platforms. The big difference between Serilog and the other frameworks is that it is designed to do structured logging out of the box. Another thing I really like about Serilog is that it can be configured via the appsetting.json
file alongside configuring through code. Changing logging configuration without touching the codebase is really helpful, especially in the production environment.
در مطلب آشنایی با Directiveها در AngularJS با نحوهی ایجاد Directive آشنا شدیم. هدف از این مطلب، آشنایی بیشتر با Directive در AngularJS است؛ یکی از بهترین فریم ورکهای جاوااسکریپتی، با قابلیت ایجاد کتابخانههایی از کامپوننتها که میتوانند به HTML اضافه شوند .
کتابخانههای جاوااسکریپتی زیادی وجود دارند. به عنوان مثال Bootstrap یکی از محبوبترین "front-end
framework" ها است که امکان تغییر در ظاهر المنتها را فراهم میکند و شامل
تعدادی کامپوننت جاوااسکریپتی نیز میباشد. مشکل کار، در هنگام استفاده از کامپوننت ها است. شخصی که در حال توسعهی HTML است
باید در کد جاوااسکریپتی خود از jQuery استفاده کند و بعنوان مثال یک Popover را فعال یا غیر فعال کند و این، یک فرآیند خسته کننده و مستعد خطا
است.
یک مثال ساده از Directives AngularJS و بررسی آن
var m = angular.module("myApp"); myApp.directive("myDir", function() { return { restrict: "E", scope: { name: "@", amount: "=", save: "&" }, template: "<div>" + " {{name}}: <input ng-model='amount' />" + " <button ng-click='save()'>Save</button>" + "</div>", replace: true, transclude: false, controller: [ "$scope", function ($scope) { … }], link: function (scope, element, attrs, controller) {…} } });
به الگوی نامگذاری directive دقت کنید. پیشوند my شبیه به یک namespace است. بنابراین اگر یک Application از دایرکتیوهای قرار گرفته در Module های متفاوت استفاده کند، به راحتی میتوان محل تعریف یک directive را تشخیص داد. این نام میتواند نشان دهندهی این باشد که این directive را خودتان توسعه دادهاید یا از یک directive توسعه داده شده توسط شخص دیگری در حال استفاده هستید. به هر حال این نحوهی نام گذاری یک اجبار نیست و به عنوان یک پیشنهاد است.
سازنده directive یک شیء را با تعدادی خاصیت باز میگرداند که تمامی آنها در سایت AngularJS توضیح داده شدهاند. در اینجا قصد داریم تا توضیحی مختصر در مورد کاری که این خصوصیات انجام میدهند داشته باشیم.
· restrict : تشخیص میدهد که آیا directive در HTML استفاده خواهد شد. گزینههای قابل استفاده ‘A’ ، ‘E’ ، ‘C’ برای attribute ، element ، class و یا comment است . پیش فرض ‘A’ برای attribute است. اما ما بیشتر علاقه به استفاده از ویژگی element برای ایجاد المنتهای UI داریم.
· scope : ایجاد یک scope ایزوله که متعلق به directive است و موجب ایزوله شدن آن از scope صدا زننده directive میشود. متغیرهای scope پدر از طریق خصوصیات تگ directive ارسال میشوند. این ایزوله کردن زمانی کاربردی است که در حال ایجاد کامپوننت هایی با قابلیت استفاده مجدد هستیم، که نباید متکی به scope پدر باشند. شیء scope در directive نام و نوع متغیرهای scope را تعیین میکنند. در مثال بالا سه متغیر برای scope تعریف شده است:
- name: "@" (by value, one-way) : علامت @ مشخص میکند که مقدار متغیر ارسال میشود. Directive یک رشته را دریافت میکند که شامل مقدار ارسال شده از scope پدر میباشد. Directive میتواند از آن استفاده کند، اما نمیتواند مقدار آن را در scope پدر تغییر دهد.
- amount: "=" (by reference, two-way) : علامت = مشخص میکند این متغیر با ارجاع ارسال میشود. Directive یک ارجاع به مقدار متغیر در scope اصلی دریافت میکند. مقدار میتواند هر نوع داده ای، شامل یک شیء complex یا یک آرایه باشد. Directive میتواند مقدار را در scope پدر تغییر دهد. این نوع متغیر، زمانیکه نیاز باشد directive مقدار را در scope پدر تغییر دهد، استفاده میشود.
- save: "&" (expression) : علامت & مشخص میکند این متغیر یک expression را که در scope پدر اجرا میشود، نگهداری میکند. اکنون directive قابلیت انجام کارهایی فراتر از تغییر یک مقدار را دارد. به عنوان مثال میتوان یک تابع را از scope پدر فراخوانی و نتیجهی اجرا را دریافت کرد.
· template : الگوی رشته ای که جایگزین المنت تعریف شده میشود. فرآیند جایگزینی تمامی خصوصیات را از المنت قدیمی به المنت جدید انتقال میدهد. به نحوه استفاده از متغیرهای تعریف شده در scope ایزوله دقت کنید. این مورد به شما امکان تعریف directive های macro-style را میدهد که نیاز به کد اضافهای، ندارند. اگرچه در بیشتر موارد الگو یک تگ ساده <div> است که از کدهای link که در زیر توضیح داده شده است استفاده میکند.
· replace : تعیین میکند که آیا الگوی directive باید جایگزین المنت شود. مقدار پیش فرض false است.
· transclude : تعیین کننده این است که محتوای directive باید در المنت کپی شود یا خیر. در مثال زیر المنت tab شامل المنتهای HTML دیگر است پس transclude برابر true است.
<body ng-app="components"> <h3>BootStrap Tab Component</h3> <tabs> <pane title="First Tab"> <div>This is the content of the first tab.</div> </pane> <pane title="Second Tab"> <div>This is the content of the second tab.</div> </pane> </tabs> </body>
· link : این تابع بیشتر منطق directive را شامل میشود. Link وظیفه دستکاری DOM ، ایجاد event listener ها و... را دارد. تابع Link پارامترهای زیر را دریافت میکند:
- scope : ارجاع به scope ایزوله شده directive دارد.
- element : ارجاع به المنتهای DOM که directive را تعریف کرده اند. تابع link معمولا برای دستکاری المنت از jQuery استفاده میکند. (یا از Angular's jqLite در صورتی که jQuery بارگذاری نشده باشد)
- controller : در مواقعی که از دایرکتیوهای تو در تو استفاده میشود کاربرد دارد. این پارامتر یک directive فرزند با ارجاعی به پدر را فراهم میکند، بنابراین موجب ارتباط directive ها میشود.
به عنوان مثال، این directive که پیاده سازی bootstrap tab را انجام داده است، میتوانید مشاهده نمایید.
موفق باشید
At the Build 2016 conference, Microsoft announced the Microsoft Bot Framework, a package of tools for building intelligent bots that could be integrated with a variety of communication platforms. With Microsoft Bot Framework Succinctly, you can jump right into building your own bots with the framework, whether you want to make bots for personal use only, or customer-facing bots for your business. Author Ed Freitas provides clear guidance from setting up a bot project in Visual Studio and writing your first bare-bones bot, to publishing one capable of searching for current flight prices.
- Introduction
- Bot Framework Overview
- Our First Bot
- Publishing Our Bot
- The QPX Express API
- Airfare Alert Bot