zoukankan      html  css  js  c++  java
  • Angular2 不明真相第一个Demo例子

    如果不是去年换工作接触到AngularJS,估计是不会花时间去学习这个框架的,毕竟是前端的框架,不是自己熟悉的领域。但是为了混得下去,去年就学习了AngularJS的一些用法,当时还整理了一些积累 《AnguarJS测试的实施步骤整理》。

    原以为可以凑合够用应付项目开发,没想到上个月公司前端扛大旗的人就说要使用Angular2,现有的AnagularJS 1.XX版本的代码会逐步升级到Angular2。去年就听说了AngularJS已经升级了,并且跟typescript联姻了,还听说typescript的语法跟C#很类似,说什么后台程序员学Angular2没有什么问题。也没有实际去学习,但目前项目需要用到,所以最近就启动了Angular2的学习过程,不指望在短期内精通,总得在新技术落地之前自己有个基础的知识,不至于手忙脚乱,也显得自己淡定。

    接着讲讲Angular2,为什么少了JS?这就是最大的升级嘛?这也是个升级,没毛病。之前AngularJS的名称用于1.XXX版本,去年7月份Angular正式发布了2.0版本,也就这里说的Angular2。2.0版本几乎是break changes,也就是说跟之前的版本不兼容了,几乎推翻重来了,所以苦逼开发者还得重复学习轮子。新版本引入了typescript,typescript是javascript的超集,通过typescript可以生成javascript代码。然后还提出了很多新的概念,比如component,import,新的module,新的指令等等。总之有得你去学习。

    这里不深入分析各个模块,自己也刚了解不久,这篇博文演示用Angular2创建一个Demo例子,用于直观感受,提提学习兴趣,找找自信心。

    一、准备环境

    a.安装Node.js和NPM

    步骤不说了,安装完成之后命令行node –v, npm -v看看版本,比如我的分别是v6.9.2和3.10.9

    b.找个开发工具,这里使用visual studio code,简单快捷

    二、准备项目

    a.准备package.json文件

    新建一个目录todo/app

    mkdir –p todo/app

    然后cd到todo目录,新建一个package.json文件,使用过node.js的应该知道这是干嘛的,类似于asp.net core的project.json,定义了一些依赖内容。

    package.json

    {
    
    "dependencies": {
    
    "@angular/common": "2.2.0",
    
    "@angular/compiler": "2.2.0",
    
    "@angular/core": "2.2.0",
    
    "@angular/forms": "2.2.0",
    
    "@angular/platform-browser": "2.2.0",
    
    "@angular/platform-browser-dynamic": "2.2.0",
    
    "reflect-metadata": "0.1.8",
    
    "rxjs": "5.0.0-beta.12",
    
    "zone.js": "0.6.26",
    
    "core-js": "2.4.1",
    
    "classlist.js": "1.1.20150312",
    
    "systemjs": "0.19.40",
    
    "bootstrap": "4.0.0-alpha.4"
    
    },
    
    "devDependencies": {
    
    "lite-server": "2.2.2",
    
    "typescript": "2.0.3",
    
    "typings": "1.4.0",
    
    "concurrently": "3.1.0"
    
    },
    
    "scripts": {
    
    "start": "concurrently "npm run tscwatch" "npm run lite" ",
    
    "tsc": "tsc",
    
    "tscwatch": "tsc -w",
    
    "lite": "lite-server",
    
    "typings": "typings"
    
    }
    
    }

    看起来又是一堆面条,这里暂时从字面意思知道三大块的意思

    dependencies:运行程序需要用到的依赖组件

    dveDependencies:用于开发环境的依赖组件

    scripts:可在命令行运行的脚本,这里包含了TypeScript的编译器和开发时用到的HTTP server

    准备了package.json之后,执行如下命令

    npm install

    这是讲package.json的依赖的包下载到本地,可以理解为nuget的restore,这个命令需要些时间,稍等。

    image

    下载完成之后,那么在todo目录下会新增一个node_modules目录,都是些依赖包信息。

    b.配置TypeScript编译器

    之前提到Angular2可用Typescript生成JS代码,这是新版的重大卖点,用typescript可以利用些高级特性生成复杂的JS代码,同时也为开发人员省去了对兼容性的考虑。

    在todo目录下创建如下tsconfig.json文件

    {
    
    "compilerOptions": {
    
    "target": "es5",
    
    "module": "commonjs",
    
    "moduleResolution": "node",
    
    "emitDecoratorMetadata": true,
    
    "experimentalDecorators": true
    
    },
    
    "exclude": [
    
    "node_modules"
    
    ]
    
    }

    c.新建一个Index.html

    好了回到最原始的一个文件,还是在todo目录下,内容如下

    <!DOCTYPE html>
    
    <html lang="en">
    
    <head>
    
    <meta charset="UTF-8">
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    
    <title>ToDo</title>
    
    <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
    
    </head>
    <body>
    <h1>Content will go here</h1>
    </body>
    </html>

    到此基本项目已经准备好,在todo目录运行用visual studio code打开,目录结构应该是这样的

    image

    然后好奇这个简单的项目能运行吗,当然可以。在todo目录下运行如下命令

    npm start

    image

    然后根据提供的Access URL,在浏览器打开就可以了(实际运行之后FireFox自动就开打了这个URL)

    image

    就显示一行内容而已,不过也证明了是可以运行的。

    通过上面的命令行可以看到实际上是运行了一个简单的HTTP Server,这个server还会监控index.html的页面变化,并实时在浏览器自动刷新显示最新的内容。比如我们把index.html更新为如下内容

    <!DOCTYPE html>
    
    <html lang="en">
    
    <head>
    
    <meta charset="UTF-8">
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    
    <title>ToDo</title>
    
    <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
    
    </head>
    
    <body class="m-a-1">
    <h3 class="bg-primary p-a-1">Junwen's To Do List</h3>
    <div class="m-t-1 m-b-1">
    <input class="form-control" />
    <button class="btn btn-primary m-t-1">Add</button>
    </div>
    
    <table class="table table-striped table-bordered">
    <thead>
    <tr>
    <th>Description</th>
    <th>Done</th>
    </tr>
    </thead>
    <tbody>
    <tr><td>Buy Flowers</td><td>No</td></tr>
    <tr><td>Get Shoes</td><td>No</td></tr>
    <tr><td>Collect Tickets</td><td>Yes</td></tr>
    <tr><td>Call Joe</td><td>No</td></tr>
    </tbody>
    </table>
    </body>
    </html>

    那么浏览器的内容会自动更新为如下

    image

    三、将Angular框架引入到项目中

    更新index.html文件,更新为

    <!DOCTYPE html>
    
    <html lang="en">
    
    <head>
    
    <meta charset="UTF-8">
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    
    <title>ToDo</title>
    
    <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
    
    <script src="node_modules/classlist.js/classList.min.js"></script>
    <script src="node_modules/core-js/client/shim.min.js"></script>
    <script src="node_modules/zone.js/dist/zone.min.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    
    </head>
    <body class="m-a-1">
    <todo-app>Angular placeholder</todo-app>
    </body>
    </html>

    这里引入了一些Angular项目需要依赖的JS文件,并且将body的内容更改成了一个自定义的标记,是不是感觉又回到了ASP.NET Core。

    目前这里todo-app的标记,浏览器是没法识别和解析的,所以直接原样输出了内容

    image

    实现todo-app指令

    接下来就是要实现todo-app的内容,切换到todo/app目录

    a.新建model.ts文件

    没错这就是我们要写的第一个typescript文件,内容如下

    export class Model{
    
    user:
    
    items;
    
    constructor(){
    
    this.user = "Junwen Luo";
    
    this.items = [
    
    new ToDoItem("Firt Item", false),
    
    new ToDoItem("Second Item", true),
    
    new ToDoItem("Third Item", false),
    
    new ToDoItem("Fourth Item", false)
    
    ];
    
    }
    
    }
    
    export class ToDoItem{
    
    action;
    
    done;
    
    constructor(action, done){
    
    this.action = action;
    
    this.done = done;
    
    }
    
    }

    大致的意思就是新建了两个类,分别是Model和ToDoItem,然后有各自的构造方法,是不是很熟悉的套路呢。

    这个语法浏览器当然不认账啦,.ts什么鬼,之前提到ts是javascript的超集,那么会在typescript编译器会将.ts文件生成对应的.js代码文件,保存.ts之后应该会生成一个model.js文件,代码如下

    "use strict";
    
    var Model = (function () {
    
    function Model() {
    
    this.user = "Junwen Luo";
    
    this.items = [
    
    new ToDoItem("Firt Item", false),
    
    new ToDoItem("Second Item", true),
    
    new ToDoItem("Third Item", false),
    
    new ToDoItem("Fourth Item", false)
    
    ];
    
    }
    
    return Model;
    
    }());
    
    exports.Model = Model;
    
    var ToDoItem = (function () {
    
    function ToDoItem(action, done) {
    
    this.action = action;
    
    this.done = done;
    
    }
    
    return ToDoItem;
    
    }());
    
    exports.ToDoItem = ToDoItem;

    如果代码没有自动生成,可以重新运行npm start。

    b.新建一个模板,还是在app目录下,新建文件名为app.component.html

    <h3 class="bg-primary p-a-1">{{getName()}}'s To Do List</h3>
    
    <div class="m-t-1 m-b-1">
    
    <input class="form-control" #todoText>
    
    <button class="btn btn-primary m-t-1" (click)="addItem(todoText.value)">
    
    Add
    
    </button>
    
    </div>
    
    <table class="table table-striped table-bordered">
    
    <thead>
    
    <tr>
    
    <th></th>
    
    <th>Description</th>
    
    <th>Done</th>
    
    <th></th>
    
    </tr>
    
    </thead>
    
    <tbody>
    
    <tr *ngFor="let item of getTodoItems(); let i = index">
    
    <td>{{i+1}}</td>
    
    <td>{{item.action}}</td>
    
    <td><input type="checkbox" [(ngModel)]="item.done" /></td>
    
    <td [ngSwitch]="item.done">
    
    <span *ngSwitchCase="true">Yes</span>
    
    <span *ngSwitchDefault>No</span>
    
    </td>
    
    <td>
    
    <button (click)="removeItem(i)">Delete</button>
    
    </td>
    
    </tr>
    
    </tbody>
    
    </table>

    这里{{}}表示的是绑定的内容,应该很好理解。

    这个模板提供了显示列表,添加和删除Item的功能,其中使用了*ngFor,*ngSwitch,*ngSwitchDefault,ngModel等这些指令。

    ngModel是用于双向绑定

    (click)是绑定单击事件

    *ngFor都比较好理解,for循环嘛

    c.新建app.component.ts,内容如下

    import { Component } from "@angular/core";
    
    import { Model, ToDoItem } from "./model";
    
    @Component({
    
    selector: "todo-app",
    
    templateUrl: "app/app.component.html"
    
    })
    
    export class AppComponent {
    
    model = new Model();
    
    getName() {
    
    return this.model.user;
    
    }
    
    getTodoItems() {
    
    return this.model.items;
    
    }
    
    addItem(newItem) {
    
    if (newItem != "") {
    
    this.model.items.push(new ToDoItem(newItem, false));
    
    }
    
    }
    
    removeItem(index) {
    
    console.log(index);
    
    if (index >= 0) {
    
    this.model.items.splice(index, 1);
    
    }
    
    }
    
    }

    这里创建一个组件,意思是匹配到todo-app的标记都要通过templateUrl对应的模板来解析显示。

    然后还定义一个类和方法,感觉像Controller。

    import的作用就是导入需要依赖的内容,类似于命名空间引入吧。

    d.新建app.module.ts

    上一个文件只是一个Component,当然还是不能够直接运行,需要通过一个Module来封装,更1.XXX版本的思想理念是一致的。

    app.module.ts内容如下
    
    import { NgModule } from "@angular/core";
    
    import { BrowserModule } from "@angular/platform-browser";
    
    import { FormsModule } from "@angular/forms";
    
    import { AppComponent } from "./app.component";
    
    @NgModule({
    
    imports:[BrowserModule, FormsModule],
    
    declarations:[AppComponent],
    
    bootstrap:[AppComponent]
    
    })
    
    export class AppModule{}

    e.新建main.ts

    到此还不能运行了,还需要一个入口,可以理解为main方法吧。

    import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
    
    import { AppModule } from "./app.module";
    
    platformBrowserDynamic().bootstrapModule(AppModule);

    f.更新index.html文件

    上面都定义好了Angular的内容,那需要加入到index.html页面中,在原有的head加入如下scripts

    <script>
    var paths = {
    "rxjs/*": "node_modules/rxjs/bundles/Rx.min.js",
    "@angular/*": "node_modules/@angular/*"
    }
    var packages = { "app": {} };
    var angularModules = ["common", "compiler", "core", "forms",
    "platform-browser", "platform-browser-dynamic"];
    angularModules.forEach(function (pkg) {
    packages["@angular/" + pkg] = {
    main: "/bundles/" + pkg + ".umd.min.js"
    };
    });
    System.config({ paths: paths, packages: packages });
    System.import("app/main").catch(function(err){ console.error(err); });
    </script>

    看起来很麻烦吧,没错就是这样,到这里应该就完成了,这样html页面就跟Angular胜利会师了,看看运行的效果

    image

    CRD没有U的功能就这么简单实现,只当做第一个体验学习吧。

    代码路径

    https://github.com/shenba2014/ProAngular2ndExamples/tree/master/FirstAngularApp/

  • 相关阅读:
    ASP.NET MVC+EF在服务端分页使用jqGrid以及jquery Datatables的注意事项
    Oracle10g在Win2008R2下因版本无法安装问题的解决
    oracle 表被锁了解决方案
    用shell获得hadoop中mapreduce任务运行结果的状态
    发现一个c++ vector sort的bug
    跳青蛙问题与变态跳青蛙问题
    关于const *和 * const
    格雷码的计算(转)
    不安装oracle客户端,如何运行sqlplus
    Sqoop 将hdfs上的文件导入到oracle中,关于date类型的问题
  • 原文地址:https://www.cnblogs.com/shenba/p/6718117.html
Copyright © 2011-2022 走看看