angular4学习笔记

1.响应用户时间 使用HostListener装饰器添加两个事件处理器,它们会在鼠标进入或离开时进行响应。

eg:  @HostListener('mouseenter') onMouseEnter() {

     this.highlight('yellow');}

@HostListener('mouseleave')onMouseLeave(){

     this.highlight(null);}

privatehighlight(color:string){

     this.el.nativeElement.style.backgroundColor=color;}

2、使用数据绑定向指令传递值

@Input() highlightColor:string

注意看@Input装饰器。它往类上添加了一些元数据,从而让该指令的highlightColor能用于绑定。

它之所以称为输入属性,是因为数据流是从绑定表达式流向指令内部的。 如果没有这个元数据,Angular就会拒绝绑定

@Input装饰器把属性设置成了公共属性。

3

生命周期的顺序

当Angular使用构造函数新建一个组件或指令后,就会按下面的顺序在特定时刻调用这些生命周期钩子方法:

钩子

目的和时机

ngOnChanges()

当Angular(重新)设置数据绑定输入属性时响应。 该方法接受当前和上一属性值的SimpleChanges对象

当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在ngOnInit()之前。

ngOnInit()

在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。

在第一轮ngOnChanges()完成之后调用,只调用一次。

ngDoCheck()

检测,并在发生Angular无法或不愿意自己检测的变化时作出反应。

在每个Angular变更检测周期中调用,ngOnChanges()和ngOnInit()之后。

ngAfterContentInit()

当把内容投影进组件之后调用。

第一次ngDoCheck()之后调用,只调用一次。

只适用于组件。

ngAfterContentChecked()

每次完成被投影组件内容的变更检测之后调用。

ngAfterContentInit()和每次ngDoCheck()之后调用

只适合组件。

ngAfterViewInit()

初始化完组件视图及其子视图之后调用。

第一次ngAfterContentChecked()之后调用,只调用一次。

只适合组件。

ngAfterViewChecked()

每次做完组件视图和子视图的变更检测之后调用。

ngAfterViewInit()和每次ngAfterContentChecked()之后调用。

只适合组件。

ngOnDestroy

当Angular每次销毁指令/组件之前调用并清扫。 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。

在Angular销毁指令/组件之前调用。

4.写服务的注意事项。

a.创建。hero.service.ts的文件,

b,将要引入的data(数据---静态数据)创建一个单独的ts。在hero.service.ts 里用import引用

c,hero.service.ts里视情况使用promise

eg:

import {Injectable} from '@angular/core'

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

import {HEROES} from '../staticdata/initdata'

@Injectable()

export class HeroService{

    getHeroes(): Promise<Hero[]> {

        return Promise.resolve(HEROES)

    }

}

d.在调用的组件里面实例化service类。注意不要这样实例化。 heroService = new HeroService(); // don't do this,不妥;即做这两份操作

1, constructor(private heroService: HeroService) { }

2, 在@Component组件的元数据底部添加providers数组属性如下: providers: [HeroService]

5、创建最外端的app壳子时需要selector设置的字符串标签在index.html 能找到。

eg:app 组件的代码

@Component({

    selector: 'app-root',

    templateUrl: './appContainer.component.html'

    })

index.html代码

<body>

  <app-root></app-root>

</body>

6、angular4的路由创建。

a、index.html页面必须有<base href= "/">

b、在app.module.ts的imports属性里面加入RouterModule.forRoot(),里面加入数组

eg:

imports: [

BrowserModule,

FormsModule,

RouterModule.forRoot([

{

path: 'heroes',

component: HeroesComponent

}

])

],

c, 路由器就把激活的组件显示在<router-outlet>里面。并且通过a标签进行导航跳转<a routerLink="/heroes">Heroes</a>

d、路由的重定向

{

path:' ',

redirectTo:'/dashboard',

pathMatch:'full'

}

e、带参数的路由配置,配置的结果是

配置: { path: 'detail/:id', component: HeroDetailComponent},

结果:/detail/11

注意:组件中数据的传输

1、从父组件的属性绑定中接收英雄数据

2、新的HeroDetailComponent应该从ActivatedRoute服务的可观察对象params中取得id参数, 并通过HeroService服务获取具有这个指定id的英雄数据。

f、路由如果是要进行迭代的话[routerLink]="['detail',hero.id]"

eg: <a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" class="col-1-4">

g.对于路由的配置可以先将其填充到一个数组里、再将定义的数组填充到router的方法里

添加RouterModule.forRoot(routes)到imports。

如果有守卫服务,把它们添加到本模块的providers中(本例子中没有守卫服务)。

eg:

const routes: Routes = [

{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },

{ path: 'dashboard', component: DashboardComponent },

{ path: 'detail/:id', component: HeroDetailComponent },

{ path: 'heroes', component: HeroesComponent }

];

@NgModule({

imports: [ RouterModule.forRoot(routes) ],

exports: [ RouterModule ]

})

7、编码式路由跳转<这三步在进行函数化路由跳转时,在该跳转组件上必须存在>

     1、从angular路由器库导入Router

          import {Router} from '@angular/router'

     2、在构造函数中注入Router(与HeroService一起)

constructor(

private router: Router,

private heroService: HeroService) { }

      3、 实现gotoDetail(),调用路由器的navigate()方法

gotoDetail(): void { this.router.navigate(['/detail',this.selectedHero.id]);}

传数值键参数

this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]);

8、路由中子组件获取参数。

a:   1.在查询参数中传递参数   /product?id=1&name=2   this.productId=this.routerInfo.snapahot.queryParams["id"]

步骤分解。| 注入ActivatedRoute   .eg:  import  {ActivatedRoute, Router} from "@angular/router"

                ||在构造函数中构造。eg: constructor(private routerIonfo:ActivatedRoute) { }

                ||||在本组件创建一个变量 eg: private productId:number

                |V在本组件中加方法。  eg:  ngOnInit(){

                        this.productId=this.routerInfo.snapshot.queryParams["id"]                     

                    }

注意:这种方法只能初始化第一次的时候获取一次数据不能,随数据变化而变化。如需要变化可以采用订阅发布者模式。

b.在路由路径中传递数据

//路由配置{path:'/product/:id'}

//路由显示方式Restful=>/product/1

/** 获取参数 *

/=>ActivatedRoute.params[id]

export class HomeComponent implements OnInit {

  private  homeId:number;

  constructor(private routerIonfo:ActivatedRoute) { }

  ngOnInit() {

    this.homeId=this.routerIonfo.snapshot.params["id"];

  }

}

优化版就是加订阅

this.routerIonfo.params.subscribe((params:Params)=>this.homeId=params["id"]);

注意: a、只有当你确定你的页面不会从自身路由到自身,或者只有一只方式路由到此页面的话就可以使用参数快照方式,不确定的话最好使用参数订阅的方式。

b、防止页面跳转没定义的路由导致程序奔溃需要配置通配符路由:

eg: { path: '**', component: PageNotFoundComponent }

c、 { path: '', redirectTo: '/heroes', pathMatch: 'full' } 在本应用中,路由器应该只有在完整的URL等于''时才选择HeroListComponent组件,因此我们要把pathMatch设置为'full'。

d、 pathMatch的另一个可能的值是'prefix',它会告诉路由器:当剩下的URL以这个跳转路由中的prefix值开头时,就会匹配上这个跳转路由。

8、路由模块

路由模块有一系列特性:

  • 把路由这个关注点从其它应用类关注点中分离出去
  • 测试特性模块时,可以替换或移除路由模块
  • 为路由服务提供商(包括守卫和解析器等)提供一个共同的地方
  • 不要声明组件

imports: [

BrowserModule,

FormsModule,

HeroesModule,

AppRoutingModule],

AppRoutingModule最后一个。最重要的是,它位于HeroesModule之后。路由配置的顺序很重要。 路由器会接受第一个匹配上导航所要求的路径的那个路由。

当所有路由都在同一个AppRoutingModule时,我们要把默认路由和通配符路由放在最后(这里是在/heroes路由后面), 这样路由器才有机会匹配到/heroes路由,否则它就会先遇到并匹配上该通配符路由,并导航到“页面未找到”路由。

一些注意

问题1.

解决方法:

引入下面代码:

import 'rxjs/add/operator/switchMap';

二、

<li *ngFor="let heroa of heroes" (click)="onSelect(heroa)">

<span>{{heroa.id}}</span><h1>{{heroa.name}}</h1>

<button class="delete"(click)="delete(hero);$event.stopPropagation()">X</button>

</li>

注:$event.stopPropagation()阻止事件冒泡,阻止它向上触发li的事件

猜你喜欢

转载自my.oschina.net/u/2542841/blog/2961247