Angular cli构建项目

本文详细介绍了使用Angular CLI构建项目的过程,包括项目初始化、添加外部框架、新建组件、编写主组件、使用Bootstrap、*ngFor遍历、指令应用、类的创建与引入、主从组件交互、服务创建与使用,以及Observable的实践。通过这些步骤,读者可以全面掌握Angular应用的开发流程。
摘要由CSDN通过智能技术生成

一,准备阶段。

初始化项目,并尝试运行:

ng new myProject

cd myProject

ng serve

二,添加外部框架:

npm install jquery --save
npm install popper.js --save
npm install bootstrap --save
由于typescript不能直接识别js,需要引入类型描述文件


npm i @types/jquery --save

文件会下载到node_modules文件夹

然后在package.json文件里添加进来:


手动在angular.json文件里,添加对js文件及css文件的引用:


三,新建组件

将需求内容分割成若干组件,然后新建这些组件。

使用命令

$ ng g component product


app文件夹内生成了相关组件文件夹,且app.module.ts内会自动引入新增组件


四,编写主组件


五,bootstrap相关代码

官方文档:

https://v4.bootcss.com/docs

导航:

  <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
    <div class="container">

    <a class="navbar-brand" href="#">导航栏</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item active">
          <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Link</a>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Dropdown
          </a>
          <div class="dropdown-menu" aria-labelledby="navbarDropdown">
            <a class="dropdown-item" href="#">Action</a>
            <a class="dropdown-item" href="#">Another action</a>
            <div class="dropdown-divider"></div>
            <a class="dropdown-item" href="#">Something else here</a>
          </div>
        </li>
        <li class="nav-item">
          <a class="nav-link disabled" href="#">Disabled</a>
        </li>
      </ul>
      <form class="form-inline my-2 my-lg-0">
        <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
        <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
      </form>
    </div>

      </div>
  </nav>

form表单:

<form>
  <div class="form-group">
    <label for="productTitle">商品名称</label>
    <input type="email" class="form-control" id="productTitle" aria-describedby="emailHelp" placeholder="Enter email">
    <!-- <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small> -->
  </div>
  <div class="form-group">
    <label for="productPrice">商品价格</label>
    <input type="email" class="form-control" id="productPrice" aria-describedby="emailHelp" placeholder="Enter email">
    <!-- <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small> -->
  </div>
  <div class="form-group">
    <label for="productCategory">商品类别</label>
    <select id="productCategory" class="form-control" name="">

    </select>
    <!-- <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small> -->
  </div>
  <!-- <div class="form-group">
    <label for="exampleInputPassword1">Password</label>
    <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
  </div>
  <div class="form-check">
    <input type="checkbox" class="form-check-input" id="exampleCheck1">
    <label class="form-check-label" for="exampleCheck1">Check me out</label>
  </div>
-->
  <div class="form-group">
  <button type="submit" class="btn btn-primary btn-block">搜索</button>
  </div>
</form>

轮播:

<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
  <div class="carousel-inner">
    <div class="carousel-item active">
      <img class="d-block w-100" src="../assets/img/1.jpg" alt="First slide">
      <div class="carousel-caption d-none d-md-block">
         <h5>大标题</h5>
         <p>文本</p>
      </div>
    </div>
    <div class="carousel-item">
      <img class="d-block w-100" src="../assets/img/2.jpg" alt="Second slide">
      <div class="carousel-caption d-none d-md-block">
         <h5>大标题</h5>
         <p>文本</p>
      </div>
    </div>
    <div class="carousel-item">
      <img class="d-block w-100" src="../assets/img/3.jpg" alt="Third slide">
      <div class="carousel-caption d-none d-md-block">
         <h5>大标题</h5>
         <p>文本</p>
      </div>
    </div>
  </div>
  <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

六,*ngFor遍历数组

product.component.ts

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

@Component({
  selector: 'app-product',
  templateUrl: './product.component.html',
  styleUrls: ['./product.component.css']
})

//控制器
export class ProductComponent implements OnInit {

// 一个Product的数组
  private products:Array<Product>

  constructor() { }


  ngOnInit() {
    this.products=[
      new Product(1,"第一个商品",12.5,3.5,"商品描述",["书籍","java"]),
      new Product(2,"第二个商品",12.5,4.5,"商品描述",["书籍","java"]),
      new Product(3,"第三个商品",12.5,2.5,"商品描述",["书籍","java"]),
      new Product(4,"第四个商品",12.5,4.5,"商品描述",["书籍","java"]),
      new Product(5,"第五个商品",12.5,3.5,"商品描述",["书籍","java"]),
      new Product(6,"第六个商品",12.5,4.5,"商品描述",["书籍","java"])
    ]
  }

}

//用来描述商品信息的类
export class Product{
  constructor(
    public id:number,
    public title:string,
    public price:number,
    public rating:number,
    public desc:string,
    public categories:Array<string>
  ){
    
  }
}

product.component.html

<div class="row">
<div *ngFor="let product of products" class="col-md-4 col-sm-4 col-lg-4">
  <div class="thumbnail">
    <img src="//placehold.it/320x150" alt="">
    <div class="caption">
      <h4 class="pull-right">1{{product.price}}</h4>
      <h4><a href="#">1{{product.title}}</a> </h4>
      <p>1{{product.desc}}</p>
    </div>
  </div>
</div>
</div>

核心代码:

*ngFor="let product of products"

再利用插值表达式将数据插入。

七,指令变更

双向绑定:

[(ngModel)]

<div><input type="text"  [(ngModel)]="hero">
<p>{{hero}}</p></div>

需要引入FormsMudule

打开 AppModule (app.module.ts) 并从 @angular/forms 库中导入 FormsModule 符号。

import { FormsModule } from '@angular/forms';
  imports: [
    BrowserModule,
    FormsModule
  ],

路径绑定:

网上方法不一,其实直接使用差值表达式即可:

src="{{carousel.url}}"

<div *ngFor="let carousel of carousels" class="carousel-item">
      <img class="d-block w-100" src="{{carousel.url}}" alt="Second slide">
      <div class="carousel-caption d-none d-md-block">
         <h5>{{carousel.title}}</h5>
         <p>{{carousel.desc}}</p>
      </div>
    </div>

[hero]="selectedHero"

Angular 的属性绑定语法

点击事件:

(click)

<div *ngFor="let hero of heroes" (click)="onSelect(hero)">
{{hero.name | uppercase}}
{{hero.id}}
</div>

定义函数:


onSelect(hero:Hero):void {
    alert(hero.name)
    // this.selecteHero = hero;
  }

class绑定:

<div *ngFor="let hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)" >
{{hero.name | uppercase}}
{{hero.id}}
</div>
  onSelect(hero:Hero):void {
     this.selectedHero = hero;
  }

当当前对象等于selectedHero中绑定的对象的时候,[class.selected]有效

*ngIf

<div *ngIf="selectedHero">
  <h2>{{ selectedHero.name | uppercase }} Details</h2>
  <div><span>id: </span>{{selectedHero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="selectedHero.name" placeholder="name">
    </label>
  </div>
</div>

根据selectedHero值,显示数组对象。


八,类的创建及引入

src/app/hero.ts

export class Hero {
  id: number;
  name: string;
}

src/app/heroes/heroes.component.ts 引入:

import { Hero } from '../hero';

类中存储的数据:

基于hero.ts中Hero类各项属性设定,所以也需要引入hero.ts。

src/app/mock-heroes.ts

import { Hero } from './hero';

export const HEROES: Hero[] = [
  { id: 11, name: 'Mr. Nice' },
  { id: 12, name: 'Narco' },
  { id: 13, name: 'Bombasto' },
  { id: 14, name: 'Celeritas' },
  { id: 15, name: 'Magneta' },
  { id: 16, name: 'RubberMan' },
  { id: 17, name: 'Dynama' },
  { id: 18, name: 'Dr IQ' },
  { id: 19, name: 'Magma' },
  { id: 20, name: 'Tornado' }
];

引入数据:

src/app/heroes/heroes.component.ts (import HEROES)

import { HEROES } from '../mock-heroes';

使用数据:

export class HeroesComponent implements OnInit {

  heroes = HEROES;

  constructor() { }

  ngOnInit() {
  }

}

九,主从组件

1,添加新组件


2,编写模板

<div *ngIf="hero">
  <h2>{{ hero.name | uppercase }} Details</h2>
  <div><span>id: </span>{{hero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="hero.name" placeholder="name">
    </label>
  </div>
</div>

3,添加 @Input() hero 属性

修改 @angular/core 的导入语句,导入 Input 符号。

import { Component, OnInit ,Input} from '@angular/core';
import { Hero } from '../hero';

添加一个带有 @Input() 装饰器的 hero 属性。

export class HeroDetailComponent implements OnInit {

  @Input() hero: Hero;

  constructor() { }

  ngOnInit() {
  }

}

4,在父组件中使用

<app-hero-detail [hero]="selectedHero"></app-hero-detail>

[hero]="selectedHero" 是 Angular 的属性绑定语法。这是一种单向数据绑定。

从父组件的 selectedHero 属性绑定到目标元素的 hero 属性,并映射到了子组件的 hero 属性。

参考地址:https://www.angular.cn/tutorial/toh-pt3#write-the-template

十,service

1,创建:

ng generate service hero

2,获取数据:

导入 Hero(属性设定) 和 HEROES(模拟数据)。

import { Hero } from './hero';
import { HEROES } from './mock-heroes';

3,创建方法用来返回数据:

添加一个 getHeroes 方法,让它返回模拟的英雄列表。

getHeroes(): Hero[] {
  return HEROES;
}

4,提供服务( HeroService)

可以在安装的时候:

ng generate service hero --module=app

或者手动提供:

打开 AppModule 类,导入 HeroService,并把它加入 @NgModule.providers 数组中。

import { HeroService } from './hero.service';
  providers: [
     HeroService,
  ],

5,使用service

导入service:

// import { HEROES } from '../mock-heroes';
import { HeroService } from '../hero.service';

把 heroes 属性的定义改为一句简单的声明。后面会对它进行赋值。

// heroes = HEROES;
  heroes: Hero[];

注入 HeroService

往构造函数中添加一个私有的 heroService,其类型为 HeroService。

  constructor(
    private heroService: HeroService
  ) { }
这个参数同时做了两件事:1. 声明了一个私有 heroService 属性,2. 把它标记为一个 HeroService 的注入点。

当 Angular 创建 HeroesComponent 时,依赖注入系统就会把这个 heroService 参数设置为 HeroService 的单例对象。

添加 getHeroes()用来获取数据

创建一个函数,以从服务中获取这些英雄数据。

  getHeroes(): void {
  this.heroes = this.heroService.getHeroes();
}

在 ngOnInit 中调用它

ngOnInit() {
  this.getHeroes();
}

也可以在构造函数中调用 getHeroes(),但那不是最佳实践。
让构造函数保持简单,只做初始化操作,比如把构造函数的参数赋值给属性。 构造函数不应该做任何事。 它肯定不能调用某个函数来向远端服务(比如真实的数据服务)发起 HTTP 请求。

应该改为在 ngOnInit 生命周期钩子中调用 getHeroes(),并且等 Angular 构造出 HeroesComponent 的实例之后,找个恰当的时机调用 ngOnInit。

十一,Observable 

/src/app/message.service.ts
import { Injectable } from '@angular/core';

@Injectable()
export class MessageService {

  messages: string[] = [];

  add(message: string) {
    this.messages.push(message);
  }

  clear() {
    this.messages = [];
  }

  constructor() { }

}

注入到 HeroService 中

/src/app/hero.service.ts

import { MessageService } from './message.service';

修改这个构造函数,添加一个私有的 messageService 属性参数。 Angular 将会在创建 HeroService 时把 MessageService 的单例注入到这个属性中。

  constructor(
        private messageService: MessageService
      ) { }

从 HeroService 中发送一条消息

修改 getHeroes 方法,在获取到英雄数组时发送一条消息。

  getHeroes():Hero[]{
        this.messageService.add('HeroService: fetched heroes');
        return HEROES;
      }

从 HeroService 中显示消息

导入 MessageService

/src/app/messages/messages.component.ts 

import { MessageService } from '../message.service';

修改构造函数,添加一个 public 的 messageService 属性。 Angular 将会在创建 MessagesComponent 的实例时 把 MessageService 的实例注入到这个属性中。

  constructor(
    public messageService: MessageService
  ) { }

这个 messageService 属性必须是公共属性,因为你将会在模板中绑定到它。

绑定到 MessageService

<div *ngIf="messageService.messages.length">

  <h2>Messages</h2>
  <button class="clear"
          (click)="messageService.clear()">clear</button>
  <div *ngFor='let message of messageService.messages'> {{message}} </div>

</div>
这个模板直接绑定到了组件的 messageService 属性上。
*ngIf 只有当在有消息时才会显示消息区。
*ngFor 用来在一系列 <div> 元素中展示消息列表。
Angular 的事件绑定把按钮的 click 事件绑定到了 MessageService.clear()。

当你把 最终代码 某一页的内容添加到 messages.component.css 中时,这些消息会变得好看一些。
刷新浏览器,页面显示出了英雄列表。 滚动到底部,就会在消息区看到来自 HeroService 的消息。 点击“清空”按钮,消息区不见了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值