[关闭]
@zChange 2017-11-10T10:04:15.000000Z 字数 6569 阅读 78

angular入门


架构模式

MVC -> MVP -> MVVM

angular/cli

angular/cli:angular脚手架,一键构建angular项目

常用指令:

ng help 查看所有指令
1. ng new projectName -- 创建angular项目
2. ng g component my-new-component -- 创建组件component ……还有很多看文档
3. ng serve 启动项目,--port 4201 指定特定的端口号
4. ng build 打包项目(webpack) --aot aot编辑
5. -- hmr 热替换

安装流程

  1. node 安装不用说了
  2. 全局安装angular-cli npm install -g @angular/cli@latest;
  3. npm如果慢可用cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org;
  4. 用cli新建angular项目 进入需要安装的文件夹后执行ng new projectName,会自动用npm安装angular的依赖包,如果觉得慢可以ctrl + c退出,到项目文件夹执行cnpm install
  5. 启动angular项目 ng serve 打开localhost:4200 默认地址;

事项

规范

定义变量和函数请申明好类型或interface

  1. // workList.model.ts
  2. export interface workList {
  3. /**
  4. * val id值
  5. */
  6. val: string;
  7. /**
  8. * text 文本值
  9. */
  10. text: string;
  11. }
  1. import { workList } from "./workList.model";
  2. getWorkList(): Promise<workList[]> {
  3. return Promise.resolve([
  4. { val: "1", text: "aa" },
  5. { val: "2", text: "bb" },
  6. { val: "3", text: "cc" },
  7. { val: "4", text: "dd" }
  8. ]);
  9. }

image_1buijlkj45sn1256q1vala1rdp21.png-120.3kB

  1. // 函数 定义申明及解释
  2. /**
  3. * 发送广播
  4. * @param val 广播val值
  5. */
  6. $broadcast(val: string) {
  7. this.broadcast.emit(val);
  8. }
  9. /**
  10. * 发送全局消息
  11. * @param message 消息值
  12. */
  13. sendMessage(message: string) {
  14. this.subject.next(message);
  15. }

image_1buik5tdn1t3p11a1ipg14q9l0c3b.png-29.1kB

image_1buik791hfiq1cnd1g7sivfbua4o.png-17.6kB

文件目录

  1. .
  2. ├── README.md
  3. ├── e2e // e2e测试
  4. ├── app.e2e-spec.ts
  5. ├── app.po.ts
  6. └── tsconfig.e2e.json
  7. ├── karma.conf.js // karma配置文件
  8. ├── package.json // 依赖包
  9. ├── protractor.conf.js // 测试的配置环境
  10. ├── src // 项目根目录
  11. ├── app
  12. ├── app.component.css
  13. ├── app.component.html
  14. ├── app.component.spec.ts
  15. ├── app.component.ts
  16. └── app.module.ts // 应用的根模块
  17. ├── assets // 放ico、图片,字体。构建后会copy到dist文件
  18. ├── environments // 配置开发环境还是生成环境
  19. ├── environment.prod.ts
  20. └── environment.ts
  21. ├── favicon.ico
  22. ├── index.html // 应用入口html文件
  23. ├── main.ts // 应用入口文件 (引导AppModule根模块启动引用)
  24. ├── polyfills.ts // 填充文件 兼容ie……
  25. ├── styles.css
  26. ├── test.ts // 单元测试入口文件
  27. ├── tsconfig.app.json
  28. ├── tsconfig.spec.json
  29. └── typings.d.ts
  30. ├── tsconfig.json // ts配置文件
  31. └── tslint.json

@NgModule

  1. import { BrowserModule } from '@angular/platform-browser';
  2. import { NgModule } from '@angular/core';
  3. import { AppComponent } from './app.component';
  4. @NgModule({
  5. declarations: [
  6. AppComponent
  7. ],
  8. imports: [
  9. BrowserModule
  10. ],
  11. providers: [],
  12. bootstrap: [AppComponent]
  13. })
  14. export class AppModule { }
  15. // import 引入访问公开对象
  16. // export 声明公开对象
  17. // declarations 申明组件(组件、指令、管道)
  18. // exports 声明其他模块,供其他Module使用
  19. // imports 引入需要的模块
  20. // providers 供应商 全局的服务 service
  21. // bootstrap 启动项 标识主视图(根组件)

路由or懒加载

基本

  1. <li routerLink='/task/workOrder' routerLinkActive="active"><a>我的任务</a></li>
  2. <router-outlet></router-outlet> // 占位符
  3. RouterModule.forRoot() // 根模块
  4. RouterModule.forChild() // 子模块
  5. redirectTo 重定向
  6. pathMatch 路由匹配 full
  7. loadChildren 懒加载 module # moduleName #号前面模块地址 #后面模块名称
  8. RouterModule.forRoot(routes, { useHash: true });
  9. (前后台路由冲突出现404)`useHash=true` 会再路由前面加个#,
  10. const routes: Routes = [
  11. { path: '', redirectTo: 'login', pathMatch: 'full' },
  12. { path: 'task', loadChildren: './workspace/workspace.module#WorkspaceModule' },
  13. { path: 'login', component: LoginComponent }
  14. ];

路由传参

  1. 传递:
  2. import { Router} from '@angular/router';
  3. this.Router.navigate(["地址",{id:id,name:name}(多个)])
  1. 接收:
  2. import { ActivatedRoute } from '@angular/router';
  3. this.activatedRoute.params.subscribe( res => { console.log(res) });
  1. html传递:
  2. <a *ngFor="let item of list" [routerLink]="['/detail', item.id]" >
  3. <a routerLink="/workspace/workone/id" >标签跳转传值</a>
  4. route设置:
  5. { path: 'detail/:id', component: nameComponent }

指令及数据绑定

数据绑定

1.单向 数据 -> 视图
image_1bs7i1l4u1rvj1ogee06episaj9.png-0.7kB
image_1bs7i3ikb1a5t16op1rsn1bfq19e31j.png-2.2kB

  1. {{name}}插入值
  2. <input [value]='name' [attr.disabled]='isDisabled'/>
  3. [attr.disabled]="'true'"
  4. [value]="'name'"

2.单向 视图 -> 数据(事件)
image_1bs7io6vnqlk12tp1f6o18deg5n2d.png-32.2kB

  1. <input
  2. (keyup)="clickMe($event,'keyup')"
  3. (keydown)="clickMe($event,'keyDown')"
  4. (change)="clickMe($event,'change')"
  5. (focus)="clickMe($event,'focus')"
  6. (blur)="clickMe($event,'blur')"
  7. />

3.双向 视图 <--> 数据

  1. <input [(ngModel)]="name"/>

内置指令

ngIf else

  1. <div *ngIf="false; else elseBlock">111111111111111</div>
  2. <ng-template #elseBlock>2222</ng-template>

ngIf then else

  1. <div *ngIf="false; then thenBlock else elseBlock">11</div>
  2. <ng-template #thenBlock>22...</ng-template>
  3. <ng-template #elseBlock>33...</ng-template>

as

  1. <div *ngIf="1111 as isShow; else elseBlock">{{isShow}}</div>
  2. //显示 1111
  3. <div *ngFor="let item of [9,8,7,6,5]; index as i; trackBy:item">
  4. {{i}} --- {{item}}
  5. </div>
  6. // 显示
  7. 0 --- 9
  8. 1 --- 8
  9. 2 --- 7
  10. …………

ngFor trackBy

  1. <div *ngFor="let item of list"></div>
  2. <div *ngFor="let item of list; trackBy:item.id"></div>

style Class

  1. <div [ngStyle]="{style: expression}"></div>
  2. <div [ngClass]="{cssClass: expression}"></div>

ngSwitch

  1. <div [ngSwitch]="conditionExpression">
  2. <div *ngSwitchCase="expression">output</div>
  3. <div *ngSwitchDefault>output2</div>
  4. </div>

dom操作

ElementRef 获取dom

  1. // html
  2. <div class="nameClass" id="nameId"></div>
  3. // ts
  4. import { ElementRef } from '@angular/core';
  5. const nameClass = this.eleRef.nativeElement.querySelector('.nameClass');
  6. this.eleRef.nativeElement.querySelector('#nameId');
  7. this.elementRef.nativeElement.contains(nameClass)

Renderer2 渲染器
用来创建元素、文本、设置属性、添加样式和设置事件监听…………

  1. changeHostState() {
  2. if (this.active) {
  3. this.renderer.addClass(this.elementRef.nativeElement, this.stateCss);
  4. return;
  5. }
  6. this.renderer.removeClass(this.elementRef.nativeElement, this.stateCss);
  7. }

拦截器及服务(httpClient)

查看taskInterceptor.service.ts
app.module.ts

生命周期钩子

  1. //8种
  2. ngOnChange();
  3. ngOninit()
  4. ngDoCheck();
  5. ngAfterContentInit()
  6. ngAfterContentChecked()
  7. ngAfterViewInit()
  8. ngAfterViewChecked();
  9. ngOnDestroy()

组件通讯

父->子: @input() 父组件添加子组件的引用@ViewChild()来获取子组件
子-> 父: @Output()
通过service
EventEmitter
订阅Subject next订阅
添加订阅后切记在ngOnDestroy生命周期中取消unsubscribe订阅

管道pipe

内置管道

  1. <div>{{1507793573000 | date: 'y-MM-dd HH:mm:ss'}}</div>
  2. <div>{{ '1507794154000000' | slice:0:13 | date:'y-MM-dd HH:mm:ss'}}</div>
  3. <div>{{'zzz' | uppercase }}</div>
  4. <div>{{'ZZZsS' | lowercase }}</div>
  5. <div>{{ 3.14159265 | number: '1.4-4' }}</div>
  6. <div>{{ { name: 'semlinker' } | json }}</div>

自定义管道

  1. @NgModule({
  2. declarations: [DateAppendzeroPipe],
  3. …………
  4. )}
  1. <div>{{ '1507794154' | dateAppendzero | date:'y-MM-dd HH:mm:ss' }}</div>
  1. import { Pipe, PipeTransform } from '@angular/core';
  2. @Pipe({
  3. name: 'dateAppendzero'
  4. })
  5. export class DateAppendzeroPipe implements PipeTransform {
  6. transform(value: any): any {
  7. return value + '000';
  8. }
  9. }

依赖注入(DI)

依赖注入

AOT(预编译) or JIT(即时编辑)编译

JIT:
image_1bs2sgej6ll91nrq1g5hrs915v11t.png-36.6kB
image_1bs2shhs91jd7sds1heam0l4uu2a.png-16.9kB

AOT:
image_1bs2s9qcr1kcr1fif1o09d5611r41g.png-35.6kB
image_1bs2s9b7618p61ndioeb2l64hs13.png-12.4kB

HMR(热替换)

HMR: ng serve --hmr;
hmr.gif-543.5kB
安装HMR

  1. npm install @angularclass/hmr -D
  2. // -D: --save-dev -S: --save

更改main.js

  1. import { enableProdMode } from '@angular/core';
  2. import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
  3. import { AppModule } from './app/app.module';
  4. import { environment } from './environments/environment';
  5. if (environment.production) {
  6. enableProdMode();
  7. }else{
  8. if (module.hot) {
  9. module.hot.accept();
  10. module.hot.dispose(() => {
  11. let _styles = document.head.querySelectorAll('style');
  12. let styles = Array.prototype.slice.call(_styles);
  13. styles
  14. .filter((style: any) => style.innerText.indexOf('_ng') !== -1)
  15. .map((el: any) => document.head.removeChild(el));
  16. })
  17. }
  18. }
  19. platformBrowserDynamic().bootstrapModule(AppModule)
  20. .catch(err => console.log(err));

删除node_modules包提示路径过长

  1. npm install rimraf -g
  2. rimraf node_modules
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注