angular2框架搭建,angular-cli使用,angular2学习

  angular红红火火不少年了,一眨眼ng4都出来了,我也只能叹息前端的突飞猛进,以及感叹本身永远追赶不上时代的步伐,可是不要紧,一个优秀的前端不在于他懂的无数的框架,而在于遇到问题时候懂得如何学习,如何解决,因此当你须要用到一个新技术的时候,你能够很快的上手,如何学习,就很是重要,学习的途经有不少,每一个人都有本身的方法。因此良好的学习能力比你蜻蜓点水的了解重要得多,固然为了求职,蜻蜓点水很重要,但对于职业生涯显得没那么重要,骚年,好好培养本身的学习能力吧,有朝一日一定大有用途。html

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

  1.电脑环境node

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

  2.安装angular-cligithub

npm install -g @angular/cli

  <1>.构建ng项目ajax

ng new my-app

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

  <2>.运行ng项目bootstrap

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,欢迎批评指正。

相关文章
相关标签/搜索