Angular

2024-06-27 18:01:46 441
Angular 是一个由 Google 维护的开源前端框架,用于构建动态的单页应用(SPA)。它基于 TypeScript 构建,提供了丰富的工具和特性,包括双向数据绑定、依赖注入、模块化开发和强大的模板系统。Angular 旨在通过简化开发流程和提高代码可维护性,帮助开发者构建高性能的应用。

特点

  1. 基于 TypeScript:Angular 采用 TypeScript 语言,提供静态类型检查和更强的开发工具支持。
  2. 双向数据绑定:数据模型和视图自动同步,简化了数据更新和界面渲染。
  3. 依赖注入:通过依赖注入机制,实现模块化和可测试的代码结构。
  4. 模块化开发:支持将应用拆分为多个模块,提高代码的可维护性和可重用性。
  5. 强大的模板系统:基于 HTML 的模板语法,提供丰富的指令和组件支持。
  6. 路由管理:内置强大的路由管理,支持动态加载和懒加载模块。
  7. CLI 工具:Angular CLI 提供了创建、构建和测试 Angular 应用的便捷命令。

使用场景

  1. 单页应用(SPA):构建复杂的单页应用,提供流畅的用户体验。
  2. 企业级应用:开发大型企业级应用,提供高性能和高可维护性。
  3. 动态表单:通过强大的表单管理,创建复杂的动态表单。
  4. 数据驱动应用:开发数据密集型应用,实时同步数据和视图。
  5. 渐进式 Web 应用(PWA):利用 Angular 的 PWA 支持,创建离线可用的 Web 应用。

安装方式

使用 Angular CLI 安装和创建 Angular 项目:

npm install -g @angular/cli
ng new my-app
cd my-app
ng serve

使用示例

创建一个简单的 Angular 组件

// app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `<h1>{{ title }}</h1>`,
  styles: [`h1 { color: blue; }`]
})
export class AppComponent {
  title = 'Hello, Angular!';
}

双向数据绑定

// app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <input [(ngModel)]="name" placeholder="Enter your name">
    <p>Hello, {{ name }}!</p>
  `
})
export class AppComponent {
  name = '';
}

路由管理

// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    AboutComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

服务和依赖注入

// data.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  getData() {
    return ['Data1', 'Data2', 'Data3'];
  }
}
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-root',
  template: `
    <ul>
      <li *ngFor="let item of data">{{ item }}</li>
    </ul>
  `
})
export class AppComponent implements OnInit {
  data: string[];

  constructor(private dataService: DataService) {}

  ngOnInit() {
    this.data = this.dataService.getData();
  }
}

常用 API 介绍

  1. Component:用于定义 Angular 组件。

    @Component({
      selector: 'app-example',
      templateUrl: './example.component.html',
      styleUrls: ['./example.component.css']
    })
    export class ExampleComponent {}
    
  2. NgModule:用于定义 Angular 模块。

    @NgModule({
      declarations: [AppComponent],
      imports: [BrowserModule],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule {}
    
  3. Service:用于定义 Angular 服务,处理业务逻辑和数据操作。

    @Injectable({
      providedIn: 'root'
    })
    export class ExampleService {
      getData() {
        return 'Example Data';
      }
    }
    
  4. Directive:用于定义 Angular 指令,扩展 HTML 功能。

    @Directive({
      selector: '[appExample]'
    })
    export class ExampleDirective {
      constructor(el: ElementRef) {
        el.nativeElement.style.backgroundColor = 'yellow';
      }
    }
    
  5. Pipe:用于定义 Angular 管道,格式化数据。

    @Pipe({
      name: 'example'
    })
    export class ExamplePipe implements PipeTransform {
      transform(value: string): string {
        return value.toUpperCase();
      }
    }
    
  6. FormBuilder:用于创建和管理表单。

    constructor(private fb: FormBuilder) {}
    
    form = this.fb.group({
      name: ['', Validators.required]
    });
    
  7. HttpClient:用于发起 HTTP 请求,处理数据通信。

    constructor(private http: HttpClient) {}
    
    getData() {
      return this.http.get('https://api.example.com/data');
    }
    

高级用法

懒加载模块

使用 Angular 的懒加载功能,按需加载模块,提高应用性能。

const routes: Routes = [
  {
    path: 'feature',
    loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule)
  }
];

自定义指令

创建自定义指令,扩展 HTML 元素的功能。

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  constructor(private el: ElementRef) {}

  @HostListener('mouseenter') onMouseEnter() {
    this.highlight('yellow');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  private highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
}

动画

使用 Angular Animations 创建复杂的动画效果。

import { trigger, state, style, transition, animate } from '@angular/animations';

@Component({
  selector: 'app-animate',
  templateUrl: './animate.component.html',
  styleUrls: ['./animate.component.css'],
  animations: [
    trigger('openClose', [
      state('open', style({
        height: '200px',
        opacity: 1,
        backgroundColor: 'yellow'
      })),
      state('closed', style({
        height: '100px',
        opacity: 0.5,
        backgroundColor: 'green'
      })),
      transition('open => closed', [
        animate('1s')
      ]),
      transition('closed => open', [
        animate('0.5s')
      ])
    ])
  ]
})
export class AnimateComponent {
  isOpen = true;

  toggle() {
    this.isOpen = !this.isOpen;
  }
}

测试

使用 Angular 的测试工具进行单元测试和端到端测试。

import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';

describe('AppComponent', () => {
  beforeEach(() => TestBed.configureTestingModule({
    declarations: [AppComponent]
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });

  it(`should have as title 'app'`, () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app.title).toEqual('app');
  });

  it('should render title', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
   

 const compiled = fixture.nativeElement as HTMLElement;
    expect(compiled.querySelector('h1')?.textContent).toContain('Welcome to app!');
  });
});

官方资料