改造app
- 新建商品详情组件productdetail,在商品详情组件中获取商品的标题
export class ProductdetailComponent implements OnInit {
productTitle:string;
constructor(private routeInfo:ActivatedRoute) {
}
ngOnInit() {
this.productTitle=this.routeInfo.snapshot.params["prodTitle"]
}}
- 新建一个home组件用于封装产品组件和轮播图组件
<div class="row carousel-container">
<app-carousel></app-carousel>
</div>
<div class="row">
<app-product></app-product>
</div>
- 在app.module中配置路由,并把路由配置注入到路由模块中去
const routeConfig:Routes=[
{path:'',component:HomeComponent},
{path:'product/:prodTitle',component:ProductdetailComponent}
]
imports: [
RouterModule.forRoot(routeConfig),
FormsModule,
ReactiveFormsModule,
HttpClientModule
],
- 在原本显示轮播图和商品列表组件的位置增加一个插座router-outlet用于显示封装了两个组件的home组件
在商品列表组件中的路由标题增加一个路由链接
<h4><a [routerLink]="['/product',product.title]"}>{{product.title}}</a></h4>
依赖注入
- 依赖注入DependencyInjection (DI),解决大量手动实例化,使用依赖注入代替我们创建方法所依赖的对象以及这些对象所依赖的对象
- 控制反转:Inversion of Control (IOC)将依赖的控制权从代码的内部转到代码的外部,控制反转和依赖注入是一体两面表达了同一个思想
- 使用依赖注入的好处:松耦合和可重用,提高可测试
- 注入器constructor(private productService: ProductService) {},这个构造函数声明时会在整个angular应用中寻找一个ProductService的实例,如果能找到在这个实例,就会把这个实例注入到ProductService对象中,然后就能够直接使用
- 如何实例化,怎样产生这个ProductService,需要指定提供器,提供器:providers:[ProductService],通过组件或者模块的providers属性来声明provider
- provider属性和useClass属性相同,都是ProductService时可以将,providers:[{provider: ProductService ,useClass: ProductService }]简写成以上的形式
- 通过一个工厂方法返回一个实例providers:[{provider: ProductService ,useFactory:()=>{} }],,会把这个工厂方法返回的实例注入到注入器中的ProductService属性上
提供器
- 生成一个product1组件,生成一个服务product,生成到一个share文件夹中,此时会提示服务已经生成但是没有被提供,必须被提供才能被使用(是因为还没有声明这个服务的提供器)
ng g service shared/product
- 通过这个服务获取商品信息,定义一个封装商品信息的类product,设置服务,并在app模块的providers中声明,并且用import引入
import { Injectable } from '@angular/core';
@Injectable()
export class ProductService {
constructor() { }
getProduct():Product {
return new Product(0,"xiaomi8",2899,"最新款小米手机")
}
}
export class Product {
constructor(
public id:number,
public title:string,
public price:number,
public desc:string
) {
}
}
- 改写product组件
import { Component, OnInit } from '@angular/core';
import {Product,ProductService} from '../shared/product.service.ts'
@Component({
selector: 'app-product1',
templateUrl: './product1.component.html',
styleUrls: ['./product1.component.css']
})
export class Product1Component implements OnInit {
product: Product;
constructor(private productService:ProductService) { }
ngOnInit() {
this.product=this.productService.getProduct()
}
}
- 这样就可以直接在product1中使用商品的信息
<div>
<h1>商品详情</h1>
<h2>名称:{{product.title}}</h2>
<h2>价格:{{product.price}}<价格2>
<h2>描述:{{product.desc}}</h2>
</div>
- 新建第二个商品组件和商品服务
ng g component product2
ng g service shared/anotherProduct
- 在product2中与product基本一致,只是多了一个providers声明
import { Component, OnInit } from '@angular/core';
import {Product,ProductService} from '../shared/product.service.ts'
import {AnotherProductService} from '../shared/another-product.service';
@Component({
selector: 'app-product1',
templateUrl: './product1.component.html',
styleUrls: ['./product1.component.css'],
providers:[{
provide:ProductService,useClass:AnotherProductService
}]
})
export class Product1Component implements OnInit {
product: Product;
constructor(private productService:ProductService) { }
ngOnInit() {
this.product=this.productService.getProduct()
}
}
- 提供器的作用域规则
- 当一个提供器声明在模块中时,它对于所有组件可见,所有组件都可以将其注入
- 当一个提供器声明在组件中时,对声明它的组件及其子组件可见,其他组件不可以租入
- 当声明在模块中的提供器和声明在组件中的提供器具有相同的名字时,声明在组建中的提供器会覆盖声明在模块中的提供器
- 一般情况下优先将服务提供器声明在模块中,只有服务必须对某个组件之外的其他组件不可见时,才应该将其声明在组件中(这种情况是少见的)
- 服务的ProductService类上方有一个@Injectable装饰器,这个装饰器意味着ProductService可以通过构造函数被注入其他服务(这个服务可以把其他服务注入到本服务中,而本服务是否能注入其他组件是由是否在providers声明决定的)
网友评论