ساخت کامپوننت با Angular Cli در انگولار

15 آبان 1397
angular-components-angular-cli

همانطور که در فصل گذشته مشاهده کردید کامپوننت ها به عنوان عضو اصلی انگولار ایفای نقش کرده و تمام فعالیت‌های مورد نیاز را انجام می‌دهند. تمام ساختار یک برنامه‌ی انگولاری با کامپوننت‌ها ایجاد می‌شود. حال در این فصل قصد داریم به ادامه‌ی آموزش مبحث کامپوننت‌ها پرداخته و با روشی مدرن‌ تر و به عبارتی ساده‌ تر کامپوننت‌ ها را توسط خط فرمان Angular CLI ایجاد کنیم. با ما همراه باشید.

ایجاد کامپوننت با خط فرمان Angular CLI

در فصل گذشته یک کامپوننت را به صورت دستی ایجاد کرده و سپس آن را مورد بررسی قرار دادیم. اما ساخت یک کامپوننت به این سختی که شما فکر می‌کنید نیست! کافیست دستور زیر را در CMD پوشه موردنظر وارد کرده تا خط فرمان CLI انگولار به صورت خودکار کامپوننت شما را ایجاد و به فایل app.module اضافه کند:

ng generate component servers

// یا به صورت اختصار

ng g c servers

پس از اجرای دستور فوق پیام‌های زیر که مبتنی بر ساخت کامپوننت است برای شما نمایش داده می‌شود. چه جالب! اگر به پوشه فایلهای خود مراجعه کنید یک پوشه با نام servers در صفحه پوشه app شما ساخته شده و به صورت خودکار فایل‌های موردنیاز برای یک کامپوننت واحد درون آن قرار گرفته است:

installing component
  create src\app\servers\servers.component.css
  create src\app\servers\servers.component.html
  create src\app\servers\servers.component.spec.ts
  create src\app\servers\servers.component.ts
  update src\app\app.module.ts

پیامی که برای ما نمایش داده است مبتنی بر ایجاد فایل‌های موردنظر در پوشه servers و همچنین بروزرسانی فایل app.module است.

علاوه بر این اگر فایل servers.component.ts را بررسی بفرمایید ملاحظه می‌کنید که در قسمت دکوراتور یا مفسر برنامه سلکتور، قالب و استایل (شکل ظاهری css) معرفی شده است. به دو دستور constructor و ngInit توجه نکنید آنها را بعدا به دقت مورد بررسی قرار می‌دهیم.

حال برای اینکه مبحث تکرار و استفاده مجدد از یک کامپوننت را مطرح کنیم. از شما تقاضا داریم ابتدا فایل app.component.html را باز کرده و تغییرات زیر را درون آن لحاظ کنید:

<h1>The App Component</h1>
<hr>
<app-servers></app-servers>

سپس در فایل servers.component.html دستورهای زیر را  قرار دهید:

<app-server></app-server>
<app-server></app-server>

سپس تغییرات را در صفحه اصلی خود بررسی کنید، با پدیده‌ی جالبی مواجه شدید! در واقع در کامپوننت servers دو بار کامپوننت server را استفاده کرده‌ایم و اگر همه چیز را مرتب انجام داده باشید با خروجی زیر روبه‌رو خواهید شد:

خروجی اضافه کردن کامپوننت تو در تو به انگولار

دقت داشته باشید که در این مبحث ما در واقع نحوه‌ی استفاده تو در تو کامپوننت‌ها را بررسی کردیم. برای درک بیشتر روی صفحه‌ی مرورگر خود و در آدرس http://localhost:4200 راست کلیک کنید و سپس گزینه‌ی inspect را انتخاب کنید (کلید میانبر F12).

در صفحه‌ای که پیش روی شما باز می‌شود مجموعه‌ی کد کامپوننت به صورت زیر می‌باشد:

<app-servers _ngcontent-c0="" _nghost-c1="">
    <app-server _ngcontent-c1=""><h3>This is a Server Component</h3></app-server>
    <app-server _ngcontent-c1=""><h3>This is a Server Component</h3></app-server>
</app-servers>

یعنی کامپوننت servers که خود فرزند کامپوننت app است به عنوان والد کامپوننت server شناخته می‌شود.

ایجاد قالب و استایل برای یک کامپوننت

تا به اینجای کار با تعریف کامپوننت آشنا شدید و نحوه‌ی کارایی آن را فرا گرفتید. در این مبحث قصد داریم نحوه‌ی ارائه‌ی شکل ظاهری و ساختاری به کامپوننت را مورد بررسی قرار دهیم.

تعریف قالب و ساختار برای هر کامپوننت در دو حالت inline (درون کد اصلی کامپوننت) یا external (به صورت کد مجدا در پوشه کامپوننت) امکان‌پذیر است.

تا الان، شکل ظاهری یک کامپوننت در فایلی با پسوند component.html قرار می‌گرفت و سپس این فایل با استفاده از ویژگی templateUrl به مفسر یا دکوراتور معرفی می‌شد. به این حالت ایجاد قالب کامپوننت به صورت external گفته می‌شود.

اما به یک نحو دیگر می‌توان قالب را برای یک کامپوننت تعریف کرد و آن تعریف internal است یعنی به جای استفاده از عبارت templateUrl دستور template را بکار برده و سپس در مقابل آن و در بین دو علامت ` ` (دکمه‌ی ~ در صفحه کلید را بدون نگه داشتن shift فشار دهید) تعریف می‌کنیم. به نمونه‌ی زیر توجه کنید:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-servers',
  template: `<div class="container">
      <app-server></app-server>
      <app-server></app-server>
  </div> `,
  styleUrls: ['./servers.component.css']
})
export class ServersComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

در این مثال یک کامپوننت را به صورت توکار یا inline قالب‌دهی کردیم. این حالت برای زمانی مورد استفاده قرار می‌گیرد که کد قالب کامپوننت شما بسیار خلاصه باشد اما بهترین حالت انتخاب یک فایل جداگانه و به روش external است.

حتما تا الان متوجه این موضوع شده‌اید که یک ویژگی با نام styleUrl در زیر templateUrl قرار گرفته است و به یک فایل که درون پوشه‌ی کامپوننت است اشاره می‌کند. درست حدس زده‌اید! در این فایل که با پسوند component.css است، تمام فایل‌های css مربوط به قالب component.html مختص این کامپوننت قرار می‌گیرد.

همچنین توجه به این نکته ضروری است که می‌توان css را بصورت inline نیز تعریف کرد. برای اینکار باید مشابه فایل html توکار، عبارت styleUrl را به Style تبدیل کرده و درون براکت [` `] کدهای css خود را قرار دهید. اما برای زیباتر شدن محیط کاری بهتر است یک فایل جداگانه برای ظاهر و استایل هر کامپوننت درنظر بگیرید.

یک نکته‌ای که باید خدمت شما عزیزان ارائه بدهیم این است: تمام فایل‌های مربوط به فریم‌ورک‌های css همچون bootstrap یا uikit را می‌توانید در پوشه‌ی assets قرار داده و سپس آن را به سیستم معرفی کنید.

برای معرفی کردن یک فایل css به صورت external باید فایل angular.json در نسخه های ۶ به بعد و angular-cli.json در نسخه های قبل از ۶ را از پوشه روت (ریشه اصلی و اولیه) باز کرده و سپس در بخش style مسیردهی خود را برای فایل‌های css مربوطه انجام دهید.

در اینجا ما فریم ورک‌ bootstrap را به مجموعه‌ی خود اضافه کرده‌ایم:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "project": {
    "version": "1.0.0-beta.32.3",
    "name": "new-cli"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "prefix": "app",
      "styles": [
        "assets/bootstrap/dist/css/bootstrap.min.css",
        "styles.css"
      ],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],
  "e2e": {
    "protractor": {
      "config": "./protractor.conf.js"
    }
  },
  "lint": [
    {
      "files": "src/**/*.ts",
      "project": "src/tsconfig.json"
    },
    {
      "files": "e2e/**/*.ts",
      "project": "e2e/tsconfig.json"
    }
  ],
  "test": {
    "karma": {
      "config": "./karma.conf.js"
    }
  },
  "defaults": {
    "styleExt": "css",
    "component": {}
  }
}

توجه: در نسخه انگولار ۶ به بعد فایل angular-cli.json به angular.json تغییر پیدا کرده است.

شما می توانید این تغییرات را به صورت زیر انجام دهید:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "angular-new": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/angular-new",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.css,
	          "assets/bootstrap/dist/css/bootstrap.min.css",
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "angular-new:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "angular-new:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "angular-new:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "karmaConfig": "src/karma.conf.js",
            "styles": [
              "src/styles.css"
            ],
            "scripts": [],
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "src/tsconfig.app.json",
              "src/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    },
    "angular-new-e2e": {
      "root": "e2e/",
      "projectType": "application",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "angular-new:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "angular-new:serve:production"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": "e2e/tsconfig.e2e.json",
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    }
  },
  "defaultProject": "angular-new"
}

در صورتیکه فایل‌های css خارجی شما متعدد هستند می‌توانید با قرار دادن یک علامت , آنها را از هم جدا کرده و به سیستم معرفی کنید. همچنین برای استفاده از فایل‌های js می‌توانید مطابق فوق آنها را در قسمت scripts تعریف کنید.

توجه داشته باشید که از این به بعد محیط نمایشی و خروجی مثال‌های ما متفاوت می‌باشد زیرا کدنویسی اختصاصی html و css توسط شرکت روکسو انجام شده تا ظاهری مناسب را برای دوستان عزیز به نمایش بگذاریم.

شما عزیزان نیز با تسلط کافی بر مباحث html و css می‌توانید ظاهر دلخواه خود را ایجاد کنید. بنابراین در مجموعه‌ی دستورها و کدهایی که ملاحظه می‌کنید، کدهای html و css را نادیده گرفته و به مفاهیم اصلی انگولار دقت کنید.

برای ویرایش ظاهر کلی برنامه به فایل app.component.html رفته و تگ‌های مربوط به فریم ورک بوت استراپ را وارد می‌کنیم، این فایل به صورت زیر ویرایش شده است:

<div class="container" dir="rtl">
    <div class="row">
        <div class="col-xs-12">
            <h1>کامپوننت App</h1>
            <hr>
            <app-servers></app-servers>
        </div>
    </div>
</div>

و در نهایت خروجی ما به صورت زیر خواهد بود:

اعمال فریم ورک Bootstrap به انگولار

تعریف متفاوت selector

همانطور که در جریان هستید سلکتورها به عنوان یکی از مهم‌ترین ویژگی‌ها مربوط به هر کامپوننت است. تعریف سلکتورها به صورتهای مختلفی امکان پذیر است که در زیر به آنها اشاره می‌کنیم:

روش ۱) در صورتیکه سلکتور به صورت زیر تعریف شود آنگاه خود کامپوننت به حالت یک تگ مورد استفاده قرار می‌گیرد.

selector: 'app-servers'

 آنگاه باید با دستور زیر از این کامپوننت استفاده کرد:

<app-servers></app-servers


روش ۲)  در صورتیکه یک سلکتور به صورت زیر تعریف شود آنگاه آن کامپوننت به صورت یک صفت در تگ‌های div یا هر تگ دیگر مورد استفاده قرار می‌گیرد:

selector: ['app-servers']

آنگاه باید با دستور زیر از این کامپوننت استفاده کرد:

<div app-servers></div>


روش ۳) اگر یک سلکتور به صورت یک کلاس که در زیر مشاهده می‌کنید تعریف شود آنگاه درون یک تگ دیگر مانند div یا غیره در فرمت کلاس استفاده می‌شود و انگولار به صورت خودکار تشخیص می‌دهد که این برنامه از فریم ورک انگولار فرمان می‌پذیرد:

selector: '.app-servers'

آنگاه باید با دستور زیر از این کامپوننت در قالب html استفاده کرد:

<div class="app-servers"></div>


در نهایت باید به این نکته توجه داشته باشید که بهترین حالت برای استفاده از این فریم روش اول است.

بسیار عالی این بخش نیز به اتمام رسید و در آن مباحث کامپوننت ها را به صورت کلی فرا گرفتید در نهایت در فصول بعدی به صورت عمیق‌تری به هر یک از مباحث می‌پردازیم. با ما همراه باشید.

توجه: دوستان عزیز آموزش ویدیویی انگولار ۶ از مقدماتی تا پیشرفته به زبان فارسی را می‌توانید با کلیک روی اینجا یاد بگیرید. 

دوره آموزش انگولار به زبان فارسی + پروژه ساخت فروشگاه اینترنتی

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش رایگان انگولار توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما (9 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

علی ظریف
21 بهمن 1398
با سلام. من اینکار را کردم اما در خروجی به جای دو سطر فقط یک سطر نمایش داده میشه: سپس در فایل servers.component.html دستورهای زیر را قرار دهید: 1 2 سپس تغییرات را در صفحه اصلی خود بررسی کنید، با پدیده‌ی جالبی مواجه شدید! در واقع در کامپوننت servers دو بار کامپوننت server را استفاده کرده‌ایم و اگر همه چیز را مرتب انجام داده باشید با خروجی زیر روبه‌رو خواهید شد:

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سید قاسم
08 اردیبهشت 1398
با سلام من دقیقا گام به گام با شما پیش رفتم اما اون فایل های مربوط به server رو ندارم شمام توضیح ندادین چجوری بسازیمشون و اینکه کجا بسازیمشون الان خروجی من یه حلقه بی نهایت از servers ها شده با این ارور ها در بخش کنسول مرورگر: ارور 1 [WDS] Disconnected! ارور2 Error: Template parse errors: 'app-server' is not a known element: 1. If 'app-server' is an Angular component, then verify that it is part of this module. 2. If 'app-server' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("[ERROR ->] "): ng:///AppModule/ServersComponent.html@0:0 'app-server' is not a known element: 1. If 'app-server' is an Angular component, then verify that it is part of this module. 2. If 'app-server' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. (" [ERROR ->]"): ng:///AppModule/ServersComponent.html@1:0

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سید قاسم
08 اردیبهشت 1398
میبخشید وقتی server رو به servers تغییر میدم اون حلقه بی نهایت ب وجود میاد . اما وقتی خود server رو به کار میبرم صفحه خالیه و این دوتا ارور رو دارم الان با توضیحات شما متوجه شدم ک باید کامپوننت server رو هم بسازم اما نمیدونم کجا و چجوری لطفا راهنمایی کنید ممنون از لطفتون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

مجتبی
17 شهریور 1397
اگر دقت کرده باشین ما در برنامه ۳ کامپوننت داریم app.component servers.component server.component احتمالا شما دو کامپونننت سرور و سرورها رو ندارید و فقط یکی از اونها رو دارید! کامپوننت سرور از طریق کامپوننت سرروها و کامپوونت سرورها از طریق کامپوننت اپ فراخوانی می‌شه

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

مجتبی
15 شهریور 1397
در انگولار نسخه ۶ به بعد فایل angular-cli.json به angular.json تغییر نام داده شده.

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

وحید
26 بهمن 1396
خسته نباشید آموزشتون فوق العاده خوب و بی نظیره فقط توی این قسمت با لود بوت استرپ سی اس اس مشکل دارم..فایل angular-cli.json رو بعد از تغییرات نیاز هست کار خاصی روش انجام بدیم؟؟ یا فقط سیو کنیم باید کار کنه؟ ممنون از پاسخگوییتون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

علی دیانت
14 مرداد 1397
سلام من دقیقا همین مشکل رو دارم من فایل angular-cli.json رو ندارم :-| یه فایل angular.json دارم که اونم انگار بی تاثیره

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

ارشان
25 آبان 1396
از فایل app.component.html این قسمت app-servers رو حذف کنید و گرنه حلقه بی نهایت می شه

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سید مسعود طباطبایی
13 شهریور 1396
سلام و خداقوت ... چند سوال داشتم ممنون میشم اگه ممکنه بهم جواب بدین: 1 - در بخشی که توضیح دادین که توی خود کامپوننت servers.component.html دوباره تگ رو استفاده کردین اون عبارتی که نوشته شده This is a server component رو کجای فایل servers.component.html استفاده کردین ؟؟ چطوری این عبارت ظاهر میشه ؟؟ 2- من خودم همین کاری رو که توی سوال 1 در موردش پرسیدم رو انجام دادم ولی عبارتایی که توی خروجی به من نشون داد خیلی زیاد بود ... منظورم اینه که شما تو خروجیتون دو بار عبارت موجود توی کامپوننت server رو نمایش دادین از من بیشمار بود ... دلیلش چیه ؟؟!

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

مجتبی
17 شهریور 1397
اگر دقت کرده باشین ما در برنامه ۳ کامپوننت داریم app.component servers.component server.component احتمالا شما دو کامپونننت سرور و سرورها رو ندارید و فقط یکی از اونها رو دارید! کامپوننت سرور از طریق کامپوننت سرروها و کامپوونت سرورها از طریق کامپوننت اپ فراخوانی می‌شه

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سبحان
03 شهریور 1396
با سلام و درود.. لطفا کد های مربوط به هر بخش رو بزارید با تشکرس

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

امید خسروجردی
07 مرداد 1396
آقا واقعا شما فوق العاده انگولار رو فارسی توضیح دادید با اینکه من چندین ویدیو و سایت مرجع نگاه کردم با زبان اصلی خیلی از نکاتی که شما بهش اشاره کردید رو ندیدم و اینجا یاد گرفتم واقعا ممنون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.