Maison >interface Web >js tutoriel >Création d'un framework de base pour Angular 18

Création d'un framework de base pour Angular 18

DDD
DDDoriginal
2024-09-13 22:16:32487parcourir

Создание базовой структуры для Angular 18

Auparavant, nous avons envisagé de créer et de mettre en place un nouveau projet Angular. Dans cet article, nous analyserons la structure de base.

Je vous rappelle que la série est consacrée au développement d'une application web de recherche de billets d'avion et d'hôtels. Le projet est basé sur un projet d'Alfa Travel - travel.alfabank.ru

Le site est constitué des blocs suivants :

  • Deux écrans : versions mobile et navigateur ;
  • 4 pages principales dans lesquelles le bloc avec le formulaire change ;
  • Section technique;
  • Rechercher des billets et des hôtels ;
  • Afficher les erreurs http - 404, 403 et 500.

Cela nous permet de mettre en avant les principales parties :

  • Mise en page de base contenant l'en-tête, le contenu et le pied de page ;
  • Le seul principal qui afficherait le formulaire requis ;
  • Résultats de recherche.

Configuration d'AppComponent

Modifiez l'AppComponent pour qu'il génère uniquement routerOutlet.

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';

@Component({
  selector: 'baf-root',
  standalone: true,
  imports: [RouterOutlet],
  template: '<router-outlet/>',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {}

Supprimez les fichiers inutilisés : app.component.spec.ts, app.component.scss et app.component.html.

Ajouter la configuration pour la version du navigateur dans app.config.browser.ts :

import { ApplicationConfig, mergeApplicationConfig } from '@angular/core';
import { provideAnimations } from '@angular/platform-browser/animations';

import { appConfig } from './app.config';

const browserConfig: ApplicationConfig = {
  providers: [provideAnimations()],
};

export const config = mergeApplicationConfig(appConfig, browserConfig);

Et importez-le dans main.ts :

import { bootstrapApplication } from '@angular/platform-browser';

import { AppComponent } from './app/app.component';
import { config } from './app/app.config.browser';

bootstrapApplication(AppComponent, config).catch((err) => console.error(err));

Ajout de marteaujs

Pour la version mobile, nous devons travailler avec des touches et des balayages, nous utilisons donc Hammerjs

Installer la dépendance :

yarn add -D hammerjs @types/hammerjs

Connectez l'animation et Hammerjs dans le navigateur :

import 'hammerjs';

import { ApplicationConfig, mergeApplicationConfig } from '@angular/core';
import { provideAnimations } from '@angular/platform-browser/animations';

import { appConfig } from './app.config';

const browserConfig: ApplicationConfig = {
  providers: [provideAnimations()],
};

export const config = mergeApplicationConfig(appConfig, browserConfig);

Vous devez définir la configuration pour Hammerjs.

Créez un nouveau dossier principal, dans lequel nous stockerons tout ce qui fait partie intégrante du projet.

mkdir src/app/core
mkdir src/app/core/lib
echo >src/app/core/index.ts
mkdir src/app/core/lib/hammer
echo >src/app/core/lib/hammer/hammer.ts

Dans Hammer.ts on précise la config :

import { EnvironmentProviders, importProvidersFrom, Injectable, Provider } from '@angular/core';
import { HAMMER_GESTURE_CONFIG, HammerGestureConfig, HammerModule } from '@angular/platform-browser';

@Injectable()
export class HammerConfig extends HammerGestureConfig {
  override overrides = {
    swipe: { velocity: 0.4, threshold: 20 },
    pinch: { enable: false },
    rotate: { enable: false },
  };
}

export function provideHammer(): (Provider | EnvironmentProviders)[] {
  return [
    importProvidersFrom(HammerModule),
    {
      provide: HAMMER_GESTURE_CONFIG,
      useClass: HammerConfig,
    },
  ];
}

Exporter vers src/app/core/index.ts :

export * from './lib/hammer/hammer';

Pour un accès rapide, ajoutez un alias à tsconfig.json :

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "sourceMap": true,
    "declaration": false,
    "experimentalDecorators": true,
    "moduleResolution": "bundler",
    "importHelpers": true,
    "target": "ES2022",
    "module": "ES2022",
    "useDefineForClassFields": false,
    "lib": ["ES2022", "dom"],
    "baseUrl": ".",
    "paths": {
      "@baf/core": ["src/app/core/index.ts"]
    }
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

Notez que vous devez également spécifier la baseUrl.

Connectez-vous dans la version du navigateur :

import { ApplicationConfig, mergeApplicationConfig } from '@angular/core';
import { provideAnimations } from '@angular/platform-browser/animations';

import { provideHammer } from '@baf/core';

import { appConfig } from './app.config';

const browserConfig: ApplicationConfig = {
  providers: [provideAnimations(), provideHammer()],
};

export const config = mergeApplicationConfig(appConfig, browserConfig);

Création d'une mise en page

La mise en page est commune à l’ensemble de l’application web. Ajoutons un nouveau dossier UI dans lequel nous stockerons les composants.

mkdir src/app/ui
mkdir src/app/ui/layout/lib
echo >src/app/ui/layout/index.ts

Exécutez la commande :

yarn ng g c layout

Déplacez le contenu vers src/app/ui/layout/lib.

On voit que tout est créé sans les attributs dont nous avons besoin et avec des fichiers de test :

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

@Component({
  selector: 'baf-layout',
  standalone: true,
  imports: [],
  templateUrl: './layout.component.html',
  styleUrl: './layout.component.scss'
})
export class LayoutComponent {}

Dans angulaire.json nous préciserons les propriétés :

{
  "@schematics/angular:component": {
    "style": "scss",
    "changeDetection": "OnPush",
    "skipTests": true
   }
}

Modifier le composant de mise en page :

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';

@Component({
  selector: 'baf-results',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './layout.component.html',
  styleUrl: './layout.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LayoutComponent {}

Ajouter un en-tête, un contenu et un pied de page :

<router-outlet name="top" />
<header>
  <router-outlet name="header" />
</header>
<main>
  <router-outlet name="main-top" />
  <router-outlet />
  <router-outlet name="main-bottom" />
</main>
<footer>
  <router-outlet name="footer" />
</footer>
<router-outlet name="bottom" />

Quelques styles :

:host {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}

header,
footer {
  flex-shrink: 0;
}

main {
  flex-grow: 1;
  overflow-x: hidden;
}

Exportez le composant vers src/app/ui/layout/index.ts :

export * from './lib/layout.component';

Et écrivez l'alias dans tsconfig.json :

{
  "paths": {
     "@baf/core": ["src/app/core/index.ts"],
     "@baf/ui/layout": ["src/app/ui/layout/index.ts"]
  }
}

Réinitialiser les styles

Avant d'afficher la mise en page, vous devez configurer les styles dans l'application.

Pour réinitialiser l'apparence par défaut dans le navigateur, procédez comme suit :

/* You can add global styles to this file, and also import other style files */
@use '@angular/cdk' as cdk;

// Hack for global CDK dialogs styles
@include cdk.overlay();

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -moz-text-size-adjust: none;
  -webkit-text-size-adjust: none;
  text-size-adjust: none;
}

blockquote {
  margin: 0;
  padding: 1rem;
}

h1 {
  margin-block-start: 1.45rem;
  margin-block-end: 1.45rem;
}

h2 {
  margin-block-start: 1.25rem;
  margin-block-end: 1.25rem;
}

h3 {
  margin-block-start: 1.175rem;
  margin-block-end: 1.175rem;
}

h4 {
  margin-block-start: 1.15rem;
  margin-block-end: 1.15rem;
}

figure {
  margin: 0;
}

p {
  margin-block-start: 1rem;
  margin-block-end: 1rem;
}

ul[role='list'],
ol[role='list'] {
  list-style: none;
}

body {
  margin: 0;
  min-height: 100vh;
  line-height: 1.5;
  font-family:
    Arial,
    ui-sans-serif,
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    sans-serif;
  font-size: 16px;
}

h1,
h2,
h3,
h4,
button,
input,
label {
  line-height: 1.1;
}

h1,
h2,
h3,
h4 {
  text-wrap: balance;
}

a:not([class]) {
  text-decoration-skip-ink: auto;
  color: currentColor;
}

img,
picture {
  max-width: 100%;
  display: block;
}

input,
button,
textarea,
select {
  font: inherit;
}

textarea:not([rows]) {
  min-height: 10rem;
}

:target {
  scroll-margin-block: 5ex;
}

La réinitialisation sera placée dans styles.scss.

Modifier index.html :

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>BuyAndFly</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet" />
    <meta name="description" content="Example Angular 18 application for search for cheap flights and hotels." />
    <link rel="preconnect" href="https://photo.hotellook.com" />
    <link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" />
    <link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png" />
    <link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png" />
    <link rel="manifest" href="/site.webmanifest" />
    <link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#172659" />
    <meta name="msapplication-config" content="/browserconfig.xml" />
    <meta name="msapplication-TileColor" content="#172659" />
    <meta name="theme-color" content="#ffffff" />
  </head>
  <body>
       <baf-root></baf-root>
  </body>
</html>

Ajoutez les favicons générés au public, ainsi que d'autres fichiers :

browserconfig.xml :

<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
    <msapplication>
        <tile>
            <square150x150logo src="/favicons/mstile-150x150.png"/>
            <TileColor>#172659</TileColor>
        </tile>
    </msapplication>
</browserconfig>

site.webmanifest:

{
    "name": "Buy & Fly",
    "short_name": "Buy & Fly",
    "icons": [
        {
            "src": "/favicons/android-chrome-192x192.png",
            "sizes": "192x192",
            "type": "image/png"
        },
        {
            "src": "/favicons/android-chrome-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
        }
    ],
    "theme_color": "#ffffff",
    "background_color": "#ffffff",
    "display": "standalone",
    "start_url": ".",
    "description": "Search for cheap flights and hotels.",
    "categories": ["travel", "education"],
    "screenshots": [
      {
        "src": "screenshot.webp",
        "sizes": "1280x720",
        "type": "image/webp"
      }
    ]
}

robots.txt:

User-agent: *
Disallow: /api

User-agent: Yandex
Disallow: /api
Clean-param: bonus&utm_source&utm_medium&utm_campaign&utm_term&utm_content&click_id&appstore&platform

Host: https://buy-and-fly.fafn.ru
Sitemap: https://buy-and-fly.fafn.ru/sitemap.xml

À la fin, nous utilisons la mise en page dans src/app/app.routes.ts :

import { Routes } from '@angular/router';

export const routes: Routes = [
  {
    path: '',
    loadComponent: () => import('@baf/ui/layout').then((m) => m.LayoutComponent),
    children: [],
  },
];

Lancez l'application :

yarn serve

Nous verrons un écran blanc :)

Добавление шапки и футера

Создадим шапку и подвал:

yarn ng g c header
yarn ng g c footer

Перенесем в ui/layout и экспортируем:

export * from './lib/footer/footer.component';
export * from './lib/header/header.component';
export * from './lib/layout.component';

Подключим их в приложении:

import { Routes } from '@angular/router';

export const routes: Routes = [
  {
    path: '',
    loadComponent: () => import('@baf/ui/layout').then((m) => m.LayoutComponent),
    children: [
      {
        path: '',
        loadComponent: () => import('@baf/ui/layout').then((m) => m.HeaderComponent),
        outlet: 'header',
      },
      {
        path: '',
        loadComponent: () => import('@baf/ui/layout').then((m) => m.FooterComponent),
        outlet: 'footer',
      },
    ],
  },
];

Запустим проект:

yarn serve

Видим созданные компоненты.

В следующей статье добавим core сервисы и интерфейсы.

Ссылки

Все исходники находятся на github, в репозитории - github.com/Fafnur/buy-and-fly

Демо можно посмотреть здесь - buy-and-fly.fafn.ru/

Мои группы: telegram, medium, vk, x.com, linkedin, site

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn