angular红红火火很多年了,一眨眼ng4都出来了,我也只能叹息前端的日新月异,以及感叹自己永远追赶不上时代的步伐,但是没关系,一个优秀的前端不在于他懂的无数的框架,而在于遇到问题时候懂得如何学习,如何解决,所以当你需要用到一个新技术的时候,你可以很快的上手,如何学习,就非常重要,学习的途经有很多,每个人都有自己的方法。所以良好的学习能力比你走马观花的了解重要得多,当然为了求职,走马观花很重要,但对于职业生涯显得没那么重要,骚年,好好培养自己的学习能力吧,有朝一日必定大有用途。

  废话不多了,我一直用的是ng1.5版本,公司也没要求要用其他的,但是我一个大学同学最近公司用了ng2做项目,遇到了问题,问我,听他随口一说,感觉说ng2和ng1差别很大,其实核心的思想是一样的,只不过把依赖注入设计更加严谨,模块的概念更加清晰了。我推荐用angular-cli来搭建前端框架。

  1.电脑环境

  首先需要你的电脑有node环境,建议高版本node,我用的是node7.×,还有npm 包管理工具,你安装了node都会默认安装npm的。

  2.安装angular-cli

npm install -g @angular/cli

  <1>.构建ng项目

ng new my-app

  应用代码位于src文件夹中。 所有的Angular组件、模板、样式、图片以及你的应用所需的任何东西都在那里。 这个文件夹之外的文件都是为构建应用提供支持用的。

  <2>.运行ng项目

cd my-app
ng serve 或者 npm start

  3.angular的模块化结构

  在你的src文件夹内部的app文件夹中,你可以看到一系列文件,其中app.module.ts是这个项目的根模块,每个项目都有一个根模块,我们习惯命名为AppModule,这个称之为项目的大脑,是项目的总指挥,所以在这个模块中不能依赖过多的东西,不要引入过多的东西,它就是整个项目的指挥中心。

NgModule是一个装饰器函数,它接收一个用来描述模块属性的元数据对象。其中最重要的属性是:

- declarations - 声明本模块中拥有的视图类。 Angular 有三种视图类:组件、指令和管道。
- exports - declarations 的子集,可用于其它模块的组件模板。
- imports - 本模块声明的组件模板需要的类所在的其它模块。
- providers - 服务的创建者,并加入到全局服务列表中,可用于应用任何部分。
- bootstrap - 指定应用的主视图(称为根组件),它是所有其它视图的宿主。只有根模块才能设置bootstrap属性。

我们平时真正开发都是在特性模块里面的,特性模块就是一个内聚的代码块专注于某个应用领域、工作流或紧密相关的功能。特性模块也有上述属性,特性模块的并不是全局,只是针对自己需要的。

  <1>创建shared模块

  在这个示例的项目中,先创建一个shared模块(ng g module shared可以直接创建整个文件夹),这个模块用于一些共享的组件,指令,过滤器。例如,我们全局任何的模块都可能需要表单验证提示这个功能,那么就把它封装成一个公用的组件,在shared.component.ts里面写入:

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

@Component({
selector: 'form-help',
template: `<div *ngIf="target.invalid">
<div *ngIf="!target._parent.submitted && target.dirty && target.errors.required" class="alert alert-danger col-sm-6">账号是必须输入的11</div>
<div *ngIf="target._parent.submitted && target.errors.required" class="alert alert-danger col-sm-6">账号是必须输入的</div>
<div *ngIf="target.dirty && target.errors.pattern" class="alert alert-danger col-sm-6">以字母开头</div>
<div *ngIf="target.dirty && target.errors.minlength" class="alert alert-danger col-sm-6">不能少于{{target.errors.minlength.requiredLength}}</div>
<div *ngIf="target.dirty && target.errors.maxlength" class="alert alert-danger col-sm-6">不能大于{{target.errors.maxlength.requiredLength}}</div>
</div>`
})
export class FormComponent {
@Input() target
constructor() {
}
} /*表单的验证规则,最大长度,最小长度,是不是必须填,正则等一系列的判断
*在这里target._parent.submitted指的就是整个表单,如果整个表单被提交过,则submitted为true,根据这个来让没有输入过的表单显示错误
*/

其中@input就是需要外部传入内部的值。然后需要在SharedModule的declarations中声明这个组件,才能起效果,如果是自己用则不需要在exports数组中声明,但是我们这个是共享模块,需要在任何其他的模块中使用的,所以就需要在exports数组中声明,表明这个组件可以被其他引入该模块的文件共享。shared.module.ts文件代码如下:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms'; import { HighlightDirective } from './shared.directive'
import { InputChangeDirective } from './shared.directive'
import {FormComponent} from './shared.component' @NgModule({
imports: [//这个模块需要的其他模块就需要在此引入,ng2把非常多的功能都拆成模块引入,比如ngModel这个指令存在FormsModule这个angular自带模块中,不引入就会报错
CommonModule,
FormsModule
],
declarations: [
FormComponent
],
providers: [ ],
exports:[FormComponent]
})
export class SharedModule { }

<2>.创建login模块

然后我们创建我们的login模块,登入模块,登入模块中组要用到上述模块的验证功能,所以在这个模块的login.module.ts文件中需要提前引入这个shared模块,代码如下:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms'; import {LoginRouterModule} from './login.routing'
import {LoginComponent} from './login.component'; import {SharedModule} from '../shared/shared.module'//引入shared模块
import {LoginService} from './login.service' @NgModule({
imports: [
CommonModule,
FormsModule,
LoginRouterModule,
SharedModule//声明shared模块 ],
declarations: [
LoginComponent,
],
providers: [LoginService]//这个是login模块的服务,即这个模块需要的ajax接口代码
})
export class LoginModule { }

这个时候就可以使用shared模块,但是angular2的验证跟ng1也有点差别,先看login.component.ts中html代码:

<div class="container">
<form class="form-horizontal" role="form" name="myForm" #forma="ngForm">
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">名字</label>
<div class="col-sm-10">
<input type="text" class="form-control" autocomplete="off" id="firstname" name="name" placeholder="请输入名字" [(ngModel)]='name' #ipt1="ngModel" minlength="3" required='true' pattern="^[a-z]+$" maxlength="6" />
<form-help [target]='ipt1'></form-help>
</div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">姓</label>
<div class="col-sm-10">
<input type="text" class="form-control" autocomplete="off" id="lastname" name="psw" placeholder="请输入姓" [(ngModel)]='psw' #ipt2="ngModel" required='true' minlength="5"/>
<form-help [target]='ipt2'></form-help>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="btn btn-default" (click)="submit(forma)">登录</button>
</div>
</div>
</form>
</div>

文件中#forma="ngForm"表明这是个ng表单,每个input都需要验证提示,则给input加上唯一的标识符#inp1=‘ngModel’,#inp2='ngModel'....,[(ngModel)]='psw'是数据双向绑定,<form-help [target]='ipt2'></form-help>就是引用了shared模块的,传入数据给定义的target,则就讲这个input的验证信息传到form-help这个组件内,会经过一系列的验证告诉你提示信息。

<3>.创建全局创建一次的方法

看到这个大家肯定很模糊,前面提到shared的模块式共享的模块,在每个其他模块都需要引入的,每次使用都是会创建实例的,但是一些全局的方法,比如ajax调用错误处理,删除提示等全局的方法,我们只需要引入一次,其他时候直接调用方法即可,并不希望每次都要引入每个特性模块。于是core模块出现了,core.service.ts文件如下:

import { Injectable } from '@angular/core';

//封装后台错误提示信息的右上角弹出红色小框
import {ToasterService} from 'angular2-toastr'; //封装一些删除,弹出输入框的确认操作
declare var swal:any;//在使用之前先声明要用到(用的是sweetalert插件,使用前在index.html里面引入相应的js文件) @Injectable()
export class CoreService { constructor(public _toaster: ToasterService) {} toasterError(title,message): void { //标题 提示信息 显示关闭按钮 消失需要时间
this._toaster.error(title, message, true, 2000);
} toasterSuccess(): void {
this._toaster.success('title', 'message', true, 2000);
} //确认删除,删除后的操作等,删除失败的处理等都需要后期的处理
comfirmDelete(type):void {
swal({
title:"确定要删除吗?",
text:'删除吧',
type:type,
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "确定!",
cancelButtonText: "取消!",
closeOnConfirm: false,
closeOnCancel: true,
showLoaderOnConfirm: true
},function(isConfirm){
if(isConfirm){
setTimeout(function(){
swal({
title: "删除成功!",
type: "success",
confirmButtonColor: "#007AFF"
});
},1000) }
})
}
}

上述就是我举得例子,一些公用的方法,不希望处处创建,也符合函数的功能,实现代码的复用。当然要在该模块的providers中声明:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import {CoreComponent} from './core.component'
import {CoreService} from './core.service' //以下两个属于angular2-toastr的东西
import {ToasterComponent, ToastComponent} from 'angular2-toastr/index'
import {ToasterService} from 'angular2-toastr'; @NgModule({
imports: [
CommonModule,
],
declarations: [
ToasterComponent,
ToastComponent,
CoreComponent
],
providers: [
ToasterService,//声明服务
CoreService
],
exports:[]
})
export class CoreModule { }

但是说到底这还是core某块中的,如何让全局都可以使用呢,只要在根模块下引入该模块即可,app.module.ts代码如下:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http'; import { AppComponent } from './app.component';
import {LoginModule} from './login/login.module'
/*app路由*/
import {routing} from './app.routing'
/*共享模块*/
import {CoreModule} from './core/core.module'
//notpage
import {NotPageComponent} from './notpage/notpage.component'
//ng2-bootstrap
import { AlertModule} from 'ng2-bootstrap'; @NgModule({
declarations: [//可以告诉 Angular 哪个组件属于AppModule ,指令和管道 — 它们也必须被添加到declarations数组
AppComponent,
NotPageComponent
], imports: [//imports数组中应该只有NgModule类。不要放置其它类型的类。
BrowserModule,
FormsModule,
HttpModule,
LoginModule,//初次加载的模块,其他的模块都是路由惰性加载的
CoreModule,//这就是coreModule的声明,可以使用这个模块全局的方法
routing,
],
providers: [],//引入服务,在所有这个模块下的都可以使用,不引入会报错,如果只需要在某个component下面使用,则只需要在某个component里面的providers里面引用即可
bootstrap: [AppComponent]
}) export class AppModule { }

4.路由

路由是每个框架必不可少的东西,我们期望的路由结构是这样的,根模块通过路由加载其他各特性模块,然后特性模块有自己的路由,引导去个特性模块里面不同的页面;为了方便演示,我在app下创建一个app.routing.ts文件,书写引导去哥特性模块的路由:

import {Routes, RouterModule} from '@angular/router';
import {NotPageComponent} from './notpage/notpage.component' const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full' },//默认到的地方
{ path: 'home', loadChildren: './home/home.module#HomeModule' },
{ path:'class', loadChildren: './class/class.module#ClassModule'},
{ path: '**', component: NotPageComponent}
];
export const routing = RouterModule.forRoot(routes);

把这个routing在AppModule的imports中引入,每个特性模块自己的路由也是这样引入。这个默认的login模块需要首先在AppModule中声明,其他惰性加载的不需要;我们再看看home这个模块的路由,在home.routing.ts中代码如下:

import {Routes, RouterModule} from '@angular/router';
import {HomeComponent} from './home.component'
import {HomeModule1Component} from './home.module1.component'
import {HomeModule2Component} from './home.module2.component' const tablesRoutes: Routes = [
{
path:'',//注意是'',并不是home
component:HomeComponent,
children: [
{ path: '', component: HomeModule1Component },
{ path: 'homemodule1', component: HomeModule1Component },
{ path: 'homemodule2', component: HomeModule2Component },
]
}
]
export const homeRouting = RouterModule.forChild(tablesRoutes);

根据home,home/homemodule1,home/homemodule2加载home模块的不同的页面。

5.期待的页面路由结构

在我们的根目录的component.ts的html中我们并不需要太多的东西,只需要他提供一个视图的窗口即可,如下:

<router-outlet></router-outlet>

在特性模块例如home中,我们需要这个特性模块的视图窗口和导航,于是home.component.ts中的html文件如下:

<div class="row">
<div class="col-sm-3">
<ul class="nav nav-pills nav-stacked">
<li><a routerLink="homemodule1" routerLinkActive="active">HomeModule1</a></li>
<li><a routerLink="homemodule2" routerLinkActive="active">HomeModule2</a></li>
<li><a routerLink="../class">Class</a></li>
<li><a routerLink="home">VB.Net</a></li>
<li><a routerLink="home">Java</a></li>
<li><a routerLink="home">PHP</a></li>
</ul>
</div>
<div class="col-sm-9">
<router-outlet></router-outlet>//这个是本特性模块的视图
</div>
</div>

6.总结

以上就是整个项目的框架搭建简述,ng2遵循的规则就是,1.我需要的模块就需要声明;2.全局的方法写在core模块,只在根模块引入;3.共享的模块写在shared模块,并在每个用到的模块中引入;其中源码在个人github上:https://github.com/jiangzhenfei/ng2-fei-cli,欢迎批评指正。

  

angular2框架搭建,angular-cli使用,angular2学习的更多相关文章

  1. 迈向angularjs2系列(8):angular cli和angular2种子项目

    文章目录 1.angular cli快速搭建项目 2.angular2-seed 3.手动配置 题外话:如何更好的阅读本篇文章 一: angular cli的安装 Angular-cli(命令行界面, ...

  2. angular2 学习笔记 ( angular cli & npm version manage npm 版本管理 )

    更新 : 2017-05-05 现在流行 Yarn ! 它是 facebook google 推出的东西. 算是补助 npm 做的不够好的地方. 源码依然是发布去 npm,只是下载接口换掉罢了哦. n ...

  3. (三) Angular2项目框架搭建心得

    前言: 在哪看到过angular程序员被React程序员鄙视,略显尴尬,确实Angular挺值得被调侃的,在1.*版本存在的几个性能问题,性能优化的"潜规则"贼多,以及从1.*到2 ...

  4. angular2.0入门---webStorm创建angular CLI项目

    创建项目之前需要先安装angular cli,(angular是用typescript编写的,所以先安装typescript,再安装angularjs-cli).打开命令窗口输入 npm instal ...

  5. ng-cli搭建angular项目框架

    原文地址 https://www.jianshu.com/p/0a8f4b0f29b3 环境准备 以下步骤都不需要事先创建文件夹,只是环境的准备过程,只有到需要搭建项目的时候才需要创建文件夹用来存放项 ...

  6. Angular开发实践(一):环境准备及框架搭建

    引言 在工作中引入Angular框架将近一年了,在这一年中不断的踩坑和填坑,当然也学习和积累了很多的知识,包括MVVM框架.前后端分离.前端工程化.SPA优化等等.因此想通过Angular开发实践这系 ...

  7. Angular企业级开发(5)-项目框架搭建

    1.AngularJS Seed项目目录结构 AngularJS官方网站提供了一个angular-phonecat项目,另外一个就是Angular-Seed项目.所以大多数团队会基于Angular-S ...

  8. .Net Core+Angular Cli/Angular4开发环境搭建教程

    一.基础环境配置1.安装VS2017v15.3或以上版本2.安装VSCode最新版本3.安装Node.jsv6.9以上版本4.重置全局npm源,修正为淘宝的NPM镜像:npminstall-gcnpm ...

  9. Angular入门,开发环境搭建,使用Angular CLI创建你的第一个Angular项目

    前言: 最近一直在使用阿里的NG-ZORRO(Angular组件库)开发公司后端的管理系统,写了一段时间的Angular以后发现对于我们.NET后端开发而言真是非常的友善.因此这篇文章主要是对这段时间 ...

随机推荐

  1. 【jQuery】 效果

    [jQuery] 效果 资料 http://www.w3school.com.cn/jquery/jquery_ref_effects.asp 1. 显示隐藏 hide(); 隐藏 show(): 显 ...

  2. c++ combination by next_permutation

    #include <iostream> #include <algorithm> #include <vector> int main() { int n, r; ...

  3. 『JavaScript』封装

    封装可以被定义为对对象的内部数据表现形式和实现细节进行隐藏.通过封装可以强制实施信息隐藏. 在JavaScript中,并没有显示的声明私有成员的关键字等.所以要想实现封装/信息隐藏就需要从另外的思路出 ...

  4. 用gradle编译任意结构的Android项目

    ## 需求 * 继续用`Eclipse`项目的结构,但是使用`gradle`编译,或者说任意的项目结构进行编译. ## 解决方案 1. Android studio的项目结构 1. Android S ...

  5. 「日常训练」「小专题·图论」 Cow Contest (1-3)

    题意 分析 问题是要看出来这是个floyd闭包问题.我没看出来- - 分析之后补充. 代码 // Origin: // Theme: Graph Theory (Basic) // Date: 080 ...

  6. VIN码识别:助力汽车后市场转型升级

    随着中国汽车市场的成熟,汽车后市场发展迅速,呈“井喷”式增长.据最新数据统计,2015年,中国汽车后市场产值突破8000亿规模,到2018年有望突破万亿. 所谓汽车后市场是指汽车销售以后,围绕汽车使用 ...

  7. Django 运行Admin 页面时出现 UnicodeDecodeError: 'gbk' codec can't decode byte XXXX解决方法

    具体报错信息 Traceback (most recent call last): File "D:\Anaconda3\lib\site-packages\django\core\hand ...

  8. Python 异步编程笔记:asyncio

    个人笔记,不保证正确. 虽然说看到很多人不看好 asyncio,但是这个东西还是必须学的.. 基于协程的异步,在很多语言中都有,学会了 Python 的,就一通百通. 一.生成器 generator ...

  9. Flask 学习笔记(二):RESTful API

    概括 URL:需要操作的对象,也就是资源 HTTP method:我要对该对象做什么(POST 增.DELETE 删.GET 查.PUT 和 PATCH 改) HTTP status code:操作的 ...

  10. Java 8手动实现一个Collector

    我们看一下Stream中的collect的方法. collect(toList())方法由Stream里的值生成一个列表,是一个及早求值的操作. Stream的of方法使用一个初始值生成新的Strea ...