Angular4的学习

2018-3-15 星期四

一、安装

注意:请现在终端/控制台窗口中运行 node -v 和 npm -v,来验证一下你正在运行的 node 6.9.x 和 npm 3.x.x 以上的版本。更老的版本可能会出现错误,更新的版本则没问题。

全局安装 Angular CLI 脚手架工具(只需安装一次)

1.使用 npm 命令安装

npm install -g @angular/cli

注意:这里的@angular/cli版本为:

image.png

2.安装 cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org

3.使用 cnpm 命令安装

cnpm install -g @angular/cli

创建项目

1.打开 cmd 找到要创建项目的目录
2.创建项目

ng new 项目名称 eg: ng new my-app

3.创建带路由的项目

ng new 项目名称 --routing

3.进入刚才创建的项目里面启动服务

cd my-app
ng serve --open //启动服务(--open可以省略)

安装插件(jquery/bootstrap......)

方法一:

npm install jquery --save
npm install bootstrap --save

方法二:

npm install bootstrap@4.0.0-alpha.6 jquery tether --save

配置项目中的.angular-cli.json文件:
style:[
  "style.css",
  "../node_modules/bootstrap/dist/css/bootstrap.css"
],
script:[
  "../node_modules/jquery/dist/jquery.js",
  "../node_modules/bootstrap/dist/bootstrap.js"
]
方法一需要:让typescript能解析文件:
npm install @types/jquery --save-dev
npm install @types/bootstrap --save-dev

在angular4中使用sass

1、利用npm工具安装sass依赖和loader

npm install node-sass --save-dev
npm install sass-loader --save-dev

2、修改.angular-cli.json文件

"styles": [
    "styles.scss"
],
"defaults":{
    "styleExt": "scss",
    "component": {}
}

注意:不用怀疑是不是写错了,不是sass,就是改成scss

3、将项目中已经存在的.css文件改成.scss【项目会自动修改的】

4、新建的component项目会直接生成.scss文件

创建组件

ng g c components/组件名 eg:ng g c components/navbar

注意:ng g component my-new-component是创建一个新的组件,默认创建在src/app目录下;ng g component components/my-new-component是创建到指定目录下面
使用组件:在 app.component.html 中添加组件的 component.ts 中 @Component 中 selector 后面的值为标签名的标签(参见页面底部)

如:navbar 组件中的 navbar.component.ts中有
@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
})
那这个组件在主页面中使用时为:
<app-navbar></app-navbar>
主要组件介绍:
import { BrowserModule } from '@angular/platform-browser';/*浏览器解析的模块*/
import { NgModule } from '@angular/core';/*angular.js 核心模块*/
import { FormsModule } from '@angular/forms';/*表单数据绑定 表单验证需要的模块*/
import { AppComponent } from './app.component';/*根组件*/
import { HttpModule } from '@angular/http';/*数据请求模块*/

@NgModule({
  declarations: [    /*引入当前项目运行的组件*/
    AppComponent,
  ],
  imports: [      /*引入当前模块运行依赖的其他模块*/
    BrowserModule,
    FormsModule
  ],
  providers: [DataService],      /*定义的服务*/
  bootstrap: [AppComponent]      /*指定应用的主视图(称为根组件)通过引导根 AppModule 来启动应用,这里一般写的是根组件*/

export class AppModule { }  /*根模块不需要导出任何东西,因为其他组件不需要导入根模块,但是一定要写*/
})
创建服务

ng g s services/服务名 eg:ng g s services/data

注意:创建服务后npm没有帮我们将服务自动添加到app.module.ts中,需要我们手动添加

在app.module.ts中添加import { DataService } from './services/data.service';
然后将 DataService 添加到providers中:providers: [DataService],


创建路由

一:直接创建一个配置好路由的项目

1、首先使用 ng new demo02 --routing 命令创建新的项目
2、引入组件,然后

假设有三个页面:主页面home、新闻页面news、新闻详情页newscontent
ng g c components/home
ng g c components/news
ng g c components/newscontent

3、找到app-routing.module.ts配置路由

import { HomeComponent } from './components/home/home.component'; 
import { NewsComponent } from './components/news/news.component'; 
import { NewscontentComponent } from './components/newscontent/newscontent.component'; 

const routes: Routes = [
 {path:'home',component:HomeComponent},
 {path:'news',component:NewsComponent},
 {
  path:'newscontent/:id',/*配置动态路由*/
  component:NewscontentComponent
 },
 {
  path: '',
  redirectTo: 'home',
  pathMatch: 'full'
 },
 {/*匹配不到路由的时候加载的组件*/
  path: '**',/*任意的路由*/
  redirectTo: 'home'
 }
];

4、找到 app.component.html 根组件模板,配置 router-outlet 显示动态加载的路由

<h1>
  <!-- routerLinkActive  为选中路由加载相应的class(激活样式)如果routerLinkActive写在a链接的父类中,那么在路由到相应的页面时,它的父类就会获得激活样式 -->
  <a routerLink="/home" routerLinkActive="active">首页</a>
  <a routerLink="/news" routerLinkActive="active">新闻</a>
</h1>

<hr>
<router-outlet></router-outlet>
image.png

二、在已经创建好的项目中添加路由

1、假设已经有相应的模块:home、news、newscontent
2、在app文件夹下新建app-routing.module.ts页面,并向其中注入模块+引入组件+配置组件+配置模块+暴露模块

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { HomeComponent } from './components/home/home.component';
import { NewsComponent } from './components/news/news.component';
import { NewscontentComponent} from './components/newscontent/newscontent.component';

const routes: Routes = [
 {
  path:'home',
  component:HomeComponent
 },
 {
  path:'news',
  component:NewsComponent
 },
 {
     /*:id  配置动态路由*/
  path:'newscontent/:id',
  component:NewscontentComponent
 },
 {
  path: '',
  redirectTo: 'home',
  pathMatch: 'full'
 },
 {/*匹配不到路由的时候加载的组件*/
  path: '**',/*任意的路由*/
  redirectTo: 'home'
 }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})

export class AppRoutingModule{ }

3、在 app.module.ts 中引入刚才定义的路由
import { AppRoutingModule } from './app-routing.module';
4、app.module.ts 里面的 import 注册这个路由模块

imports: [
   BrowserModule,
   AppRoutingModule
]

5、找到 app.component.html 根组件模板,配置 router-outlet 显示动态加载的路由

<h1>
  <!-- routerLinkActive  为选中路由加载相应的class(激活样式) -->
  <a routerLink="/home" routerLinkActive="active">首页</a>
  <a routerLink="/news" routerLinkActive="active">新闻</a>
</h1>

<hr>
<router-outlet></router-outlet>

路由的动态传值
1、配置动态路由,上文有(:id)
2、获取动态路由的值

注意:那个页面需要动态路由,在哪个页面引入
import { ActivatedRoute } from '@angular/router';


constructor(private route:ActivatedRoute) { }

 ngOnInit() {
  //获取动态路由
  console.log(this.route.params['_value'].id)
  或者:使用this.route.params.subscribe(data=>this.id=data.id);
 }

1、
image.png

2、
image.png

image.png


创建管道

ng g pipe 管道名 eg:ng g pipe my-new-pipe 或者 ng g p my-new-pipe 类似写法相同

创建类

ng g class my-new-class

创建指令

ng g directive my-new-directive

创建Guard

ng g guard my-new-guard

创建interface

ng g interface my-new-interface

创建enum

ng g enum my-new-enum

创建module

ng g module my-module

父子组件之间的传递和引用

1、嵌套

组件之间的嵌套和在主页面中引用组件的方式一样,找到子组件的selector,然后在父组件的页面中引用标签名,例:
<app-question *ngFor="let question of questions"></app-question>

2、子组件引用父组件的数据

传递数据需要在父组件中设定属性,给属性赋值:
<app-question *ngFor="let question of questions" [question]="question"></app-question>
然后子组件的component.ts中添加依赖 Input :
import { Component, OnInit, Input } from '@angular/core';
再在函数中添加 @Input 接收父组件中被赋值的属性:
@Input("question") question:Question;



Angular的一些指令

*ngFor普通循环
<ul>
    <li *ngFor="let item of list">{{item}}</li>
</ul>

循环的时候设置key

<ul>
  <li *ngFor="let item of list;let i = index">{{item}} --{{i}}</li>
</ul>
或者:
<ul>
  <li *ngFor="let item of list;index as i">{{item}}---{{i}}</li>
</ul>

template循环数据

<ul>
  <li template="ngFor let item of list">{{item}}</li>
</ul>
*ngIf 条件判断
<p *ngIf="list.length > 3">这是 ngIf 判断是否显示</p>
<p template="ngIf list.length > 3"> 这是 ngIf 判断是否显示</p>
(click)="getDate()" 执行事件
<button class="button (click)="getData()">点击按钮触发事件</button>
button class="button" (click)="setData()">点击按钮设置数据</button>
etData(){/*自定义方法获取数据*/ //获取alert(this.msg)};
setData(){//设置值 this.msg="这是设置的值";}
绑定属性

使用[属性]=“值”进行属性绑定(属性如果不加[],那么就直接是传统的赋值,加上[]就是angular中属性绑定)

<!-- 例子 -->
<p>2.属性绑定:</p>
<img src="{{src}}"/>
<p>3.属性绑定:</p>
<img [src]="src"/>

<!-- ts -->
src:string = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png";
class类的绑定

1、直接使用[class]DOM绑定会覆盖之前的class

<div class="a b" [class]="classname"></div>
//ts文件
classname:string = "c";

2、使用[class.类名]=”boolean”来判断是否追加这个class

<div class="a b" [class.c]="isShow"></div>
// 或者使用表达式
<div class="a b" [class.c]="isShow == true"></div>
//ts文件
isShow:boolean = true;

3、使用对象显示

<div [ngClass]={a:isA,b:isB,c:isC}></div>
//ts文件
isA:boolean = true;
isB:boolean = true;
isC:boolean = true;
//或者
<div [ngClass]="classGroup"></div>
//ts文件
classGroup:any = {
    a:true,
    b:true,
    c:true
  }
样式绑定

1、绑定单个样式

<p [style.color]="isRed?'red':'blue'">我是测试样式的</p>
<p [style.color]="redColor">我是测试样式的</p>
// ts文件
isRed:boolean = true;
redColor:string = "red";

2、带单位的

<p [style.font-size.em]="fontSize?1:3">我是测试样式的</p>
// ts
fontSize:boolean = false;

3、绑定多个样式

<div [ngStyle]="styleGroup"></div>
// ts
styleGroup:any = {
  width:"100px",
  height:"100px",
  border:"1px solid #ddd",
  margin:"20px"
}
综合运用的一次示例

在for循环中使用属性绑定和事件绑定:

<!-- html -->
  <div class="my-list" *ngFor="let item of typeList;index as i" (click)="item.ev()" [class.list3]="i == 2">
    <div>
      <ion-icon name="{{item.icon}}" [style.color]="item.color"></ion-icon>
      {{item.name}}
    </div>
    <ion-icon name="ios-arrow-forward"></ion-icon>
  </div>
.my-list{
    display: flex;
    justify-content: space-between;
    padding: 11px 30px 11px 20px; 
    font-size: 16px;
    color: #333;
    border-top: 1px solid #eee;
    div{
      width: 150px;
      ion-icon{
        margin-right: 13px;
      }
    }
    &.list3{
      border-bottom: 1px solid #eee;
    }
 }
// ts
typeList = [
    {
      ev: ()=>{this.hello()},
      icon: 'star',
      color: '#63c860',
      name: '投放记录',
    },
    {
      ev: ()=>{this.world()},
      icon: 'ios-clock',
      color: '#7699ff',
      name: '我的积分'
    },
    {
      ev: ()=>{ this.name()},
      icon: 'ios-home',
      color: '#ffd700',
      name: '兑换记录'
    }
];
constructor(...){...}
hello(){
  console.log('hello');
}
world(){
  console.log('world');
}
name(){
  console.log('xiao ming');
}
表单处理
<input type="test" (keyup)="keyUpFn($event)"/>
keyUpFn(e){console.log(e)}
双向数据绑定
<input [(ngModel)]="inputValue">
注意引入:FormsModule
import { FormsModule } from '@angular/forms';
@NgModule({
    declarations:[
       AppComponent,
       HeaderComponent,
       FooterCompoonent,
       NewsComponent
   ],
  imports:[
      BrowserModule,
      FormsModule
  ],
  providers: [],
    bootstrap: [AppComponent]
})
export class AppModule{   }

使用

<input type="text" [(ngModel)]="inputValue"/>
{{inputValue}}
Todolist 功能

html部分

<input type="text" [(ngModel)]="username">
<button (click)='addData()>增加</button>
<ul>
   <li *ngFor="let item of list>{{item}}</li>
</ul>

js部分

export class TodolistComponent implements OnInit {
  list:any[];
  username:any;
  
  consturctor(){

  }
  
  ngOnInit(){
    this.list=[];
    this.username='';
  }
  addData(){
    alert(this.username);
    this.list.push(this.username);
  }

}

其他的一些内容

import { Component, OnInit } from '@angular/core';    /*引入 angular 核心*/

@Component({
  selector: 'app-question-list',    /*使用这个组件的名称*/
  templateUrl: './question-list.component.html',    /*html模板*/
  styleUrls: ['./question-list.component.css']    /*css 样式*/
})
export class QuestionListComponent implements OnInit {

  constructor() {   }    /*构造函数*/

  ngOnInit() {      /*初始化加载的生命周期函数*/
   
  }
}

关于打包

1、执行打包命令:ng build --prod --aot后会生成dist文件,但有可能打包出来的文件里面的index.html什么都不显示,解决办法:

将项目/src 目录下的index.html内容修改:
<base href="/"> 修改为
<base href="./"> 即可。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AdminConsole</title>
  <base href="./">      <!-- 这里是重点 -->
 
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
</body>
</html>

2、将项目发布到服务器上后图片路径都为assets/.......或者./assets/.....
3、项目发布到服务器刷新显示404问题:
解决方法:
配置app.module.ts

import {HashLocationStrategy , LocationStrategy} from '@angular/common';

@NgModule({
  declarations: [AppCmp],
  bootstrap: [AppCmp],
  imports: [BrowserModule, routes],
  providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]
});

主要添加的代码:
providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]
这样设置后,访问angular站点,会自动在根节点后面加一个#锚点。再次刷新便不会报404错误了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容