【Angular2】Angular2——Hello World!

申屠宗清
2023-12-01

前言

        作为例子之父,Hello World是每个语言学习之时做的第一个例子,今天我们就来比较一下,使用ES5规范的Hello World和使用Typescript的Hello World有什么异同吧。

ES5

        ES全称ECMAScript,它实际上是一种脚本在语法和语义上的标准。实际上JavaScript是由ECMAScript,DOM和BOM三者组成的。

        ES5相信很多人都用过,绝大多数浏览器都支持ES5,当ES6(ES2015)出来时,加入了很多新特性,对ES5来说,这是一个巨大的飞跃。但是,并非大部分浏览器都能跟上这个脚步,我们如何才可以在还不支持ES6的浏览器中运行ES6呢?

Typescript

        TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。

        它可以将符合ES6规范的ts代码转换为适合ES5规范的js代码,也就是说,我们可以在仅仅支持ES5的浏览器上使用更多特性的ES6代码规范,是不是超酷呢?

代码

ES5

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <app></app>
    <script src="https://unpkg.com/zone.js@0.6.12/dist/zone.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
    <script src="https://unpkg.com/rxjs@5.0.0-beta.6/bundles/Rx.umd.js"></script>
    <script src="https://unpkg.com/@angular/core@2.0.0-rc.4/bundles/core.umd.js"></script>
    <script src="https://unpkg.com/@angular/common@2.0.0-rc.4/bundles/common.umd.js"></script>
    <script src="https://unpkg.com/@angular/compiler@2.0.0-rc.4/bundles/compiler.umd.js"></script>
    <script src="https://unpkg.com/@angular/platform-browser@2.0.0-rc.4/bundles/platform-browser.umd.js"></script>
    <script src="https://unpkg.com/@angular/platform-browser-dynamic@2.0.0-rc.4/bundles/platform-browser-dynamic.umd.js"></script>
    <script src="./app.js"></script>
</body>
</html>
app.js
var App = ng.core.Component({
    selector: 'app',
    template: '<h1>Hello {{target}}!</h1>'
})
.Class({
    constructor: function () {
        this.target = 'world';
    }
});
ng.platformBrowserDynamic.bootstrap(App);

Typescript

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title><%= TITLE %></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- inject:css -->
    <!-- endinject -->
</head>
<body>
    <app>Loading...</app>
    <!-- inject:js -->
    <!-- endinject -->
    <%= INIT %>
</body>
</html>
app.ts
import {Component} from  '@angular/core'
import {bootstrap} from "@angular/platform-browser-dynamic";
@Component({
    selector: 'app',
    templateUrl: './app.html',
})
class App {
    target:string;
    constructor() {
        this.target = 'world';
    }
}
bootstrap(App);
app.html
<h1>Hello {{target}}!</h1>
输出后的app.js
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var core_1 = require('angular2/core');
var browser_1 = require("angular2/platform/browser");
var App = (function () {
    function App() {
        this.target = 'world';
    }
    App = __decorate([
        core_1.Component({
            selector: 'app',
            templateUrl: './app.html',
        }),
        __metadata('design:paramtypes', [])
    ], App);
    return App;
}());
browser_1.bootstrap(App);
输出后的index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Switching to Angular 2</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- inject:css -->
    <link rel="stylesheet" href="/node_modules/.3.3.7@bootstrap/dist/css/bootstrap.min.css">
    <!-- endinject -->
</head>
<body>
    <app>Loading...</app>
    <!-- inject:js -->
    <script src="/node_modules/.0.35.2@es6-shim/es6-shim.min.js"></script>
    <script src="/node_modules/.0.1.2@reflect-metadata/Reflect.js"></script>
    <script src="/node_modules/.0.19.41@systemjs/dist/system.src.js"></script>
    <script src="/node_modules/.0.6.26@zone.js/dist/zone.js"></script>
    <script src="/node_modules/.5.0.0-beta.6@rxjs/bundles/Rx.min.js"></script>
    <!-- endinject -->
<script>
    System.config({"defaultJSExtensions":true,"paths":{"bootstrap":"/dist/dev/bootstrap","markdown":"/node_modules/markdown/lib/markdown","immutable":"/node_modules/immutable/dist/immutable.js"},"map":{"rxjs":"/node_modules/rxjs","@angular":"/node_modules/@angular"},"packages":{"@angular/core":{"main":"index.js","defaultExtension":"js"},"@angular/compiler":{"main":"index.js","defaultExtension":"js"},"@angular/common":{"main":"index.js","defaultExtension":"js"},"@angular/platform-browser":{"main":"index.js","defaultExtension":"js"},"@angular/platform-browser-dynamic":{"main":"index.js","defaultExtension":"js"},"@angular/router-deprecated":{"main":"index.js","defaultExtension":"js"},"@angular/http":{"main":"index.js","defaultExtension":"js"},"rxjs":{"defaultExtension":"js"}}});
    System.import("./app")
        .catch(function () {
            console.log("Report this error to https://github.com/mgechev/switching-to-angular2/issues", e);
    });
</script>
</body>
</html>

代码解释

        对于ES5规范下的代码,相信我们都很容易懂,app.js中定义了<app>这个组件,在我们的HTML中(需要引用那么多的JS插件,具体作用自行搜索吧)直接引用则会得到想要的效果(显示Hello World!)。

        但是对于Typescript,我们就需要解释一番了。

首先,我们从它的index.html来入手

        Angular2本身是一个JS文件,所以我们需要一个script标签来引入它,并且需要引入一些Angular/TypeScript依赖的文件:

·es6-shim(为了兼容旧浏览器)

·angular2-polyfills(提供跨浏览器的一些基本的标准化,包含的代码专门用于zone,promise和reflection)

·SystemJS(模块加载器,帮助创建模块和解决模块之间的依赖,使复杂的模块加载在浏览器端过程变得容易)

·RxJS(库用与在JS中进行反应式编程)

        也就是我们在输出后的index.html的<body>中添加的标签。

接下来是app.ts文件

导入模块

        import语句定义了在我们代码中需要用到的模块,这里我们导入了两个模块,Component和Bootstrap。我们从@angular/core模块导入了Component模块,@angular/core这部分告诉我们程序在哪里可以找到我们依赖;同样从模块@angular/platform-browser-dynamic中导入bootstrap模块。

创建组件

        我们Angular应用中编写HTML标签,浏览器只认识内置的标签,如<select>、<form>等,但是,如果我们想让它认识新的标签呢?接下来,我们来创建一个组件。

        一个基本组件分为两部分:

·Component注解

·定义组件的类

        注解会作为元数据添加到您的代码里。当我们在App类上使用@Component,会装饰App类成为一个组件。比如,我们希望用<app></app>标签来使用组件,只需要将@Component配置中的selector属性设置为app即可。这里的selector属性表示对应的DOM元素将要被组件使用,这样,在模板中<app></app>标签会使用这个组件类进行编译。

@Component({
    selector:'app'
})

添加模板

        我们可以通过@Component中的template选项来添加模板:
@Component({
    selector:'app',
    template:'
        <div>
            Hello World!
        </div>
        '
)}
        或者通过@Component中的templateUrl选项来添加模板链接(引入的模板)
@Component({
    selector:'app',
    templateUrl:'./app.html'
)}

引导应用

        文件的最后一行“Bootstrap(App)”将启动应用,第一个参数表明,该应用的主(main)组件是App。一旦被引导,在index.html文件中<app></app>会被组件渲染。

加载应用

        要运行应用,需要做两件事:
1、告诉HTML文件导入的app文件
2、在body中使用<app>组件
在输出的index.html文件中,有这样一行语句:
System.import("./app")
        这行告诉System.js要加载app.js作为主要入口。(但是现在还没有一个app.js,我们的文件还是app.ts,现在就要用到将ts转换为js,非常简单的一行代码,有兴趣的小伙伴可以自行查找)

效果

        如果没有错误的话,启动该程序后,将会在页面上看到Hello World!字样。

总结

        这篇博客总结了一个简单Hello World程序在两种不同规范下的形式,说它简单,因为它只是一个静态的页面,组件的数据也是固定的,从下个博客开始,就要添加更多的新特性。敬请期待吧。

 类似资料: