本系列从Java程序员的角度,带大家理解前端Angular框架。

本文是入门篇。笔者认为亲自动手写代码做实验,是最有效最扎实的学习途径,而搭建开发环境是学习一门新技术最需要先学会的技能,是入门的前提。

作为入门篇,本文重点介绍Angular的开发、编译工具:npm, yarn, Angular CLI,它们就像Java在中的Maven,同时顺便介绍一些Angular的概念。学习之后,希望你能够在自己的环境下练习、探索、编写出自己的第一个基于AngularWeb应用。

在开始介绍之前,先了解下一些背景知识,理解单页应用与传统基于模板的多页应用在Web开发思路的不同。

什么是单页应用(Single Page Application,SPA)

单页应用是Web前端发展的主流趋势。

服务端渲染

传统的Web前端是多页应用的,客户端浏览器向服务器提交请求,服务端通过处理HTML模板(如PHP,ASP,JSP等),生成HTML文本返回给浏览器,浏览器重新渲染并且展示。HTML完全有后端决定,因此称为“服务端渲染”。客户端每次拿到都是一个HTML页面,这样一个Web应用就有很多页面,因此叫多页应用。

服务器 ----(html页面)---> 浏览器
  • 1

由于浏览器每次都要解析整个HTML并渲染,因此效率较低,每次即使更新一个数据也要在网络上传输整个HTML文本,占用更多的带宽。

客户端渲染

不同于传统多页应用,在SPA应用中,客户端浏览器向服务器提交请求,服务端返回数据(通常是json格式)给浏览器,浏览器中的js更新相应部分的DOM,从而更新展示。渲染的过程是在客户端浏览器完成的。

服务器 ----(json数据)---> 浏览器
  • 1

优点:

  1. 局部刷新。无需每次都进行完整页面请求。
  2. 天然的前后端分离。后端不再有渲染展示逻辑,只要专注业务逻辑并能够向前端提供数据;而前端只关注如何展示数据、处理用户交互,提高用户体验。这很像C/S架构,富客户端,只不过客户端是浏览器中的js脚本。
  3. 计算量转移。原本需要后端渲染的任务转移给了前端,减轻了服务器的压力。

缺点:

  1. 首次打开较慢。由于是富客户端(js脚本),当客户端首次打开网页,需要先下载一堆jscss后才能看到页面。对于这一点,SPA也有应对方案,比如可以(1)分拆打包(把js拆成多个包,首屏用到的先传);(2)先传个友好的加载页面;(3)同构(第一次加载是采用后端渲染,以后用前端渲染)。
  2. 不方便搜索引擎。传统的搜索引擎会从HTML中抓取数据,导致前端渲染的页面无法被抓取。不过这一点,随着SPA的流行,Google爬虫也可以像浏览器一样理解js脚本了。

流行的SPA框架

流行的SPA框架有React, Vue, Angular。本文基于Angular 2/4/5+(不是Angular 1.xAngularJS)。

node.js

就像Java开发需要JDKAngular开发需要node.jsJava编译出来的字节码需要Java虚拟机JRE执行,而如果想在浏览器以外执行JavaScript代码,也需要类似的虚拟机平台,也就是node.js

类似JDKnode.js下载之后也不需要安装,只要加到PATH路径下即可。这里需要node.js是因为很多前端开发工具是有JavaScript写成的,如npm,它们需要node.js这个虚拟机。

项目依赖管理工具

Java中的maven,开发Angular可以使用npm或者yarn。其中npmnode.js自带的,可以直接使用。

另外,npm还有maven不具备的能力,它可以从网上下载并安装软件,类似于Linux中的yum。比如,yarn可以通过npm下载安装:

npm install --global yarn
  • 1

npm作为项目依赖管理有个缺点,它没有本地仓库,对同一个依赖,不管其他项目是否已经下载过,只要这个项目没有,它都从网上下载。下载后存在每个项目下的node_modules/路径下。相比,maven有本地仓库,对同一个依赖只会下载一次,存在~/.m2/repository/下。

npm不同的是,yarn无需互联网连接就能安装本地缓存的依赖项,它提供了离线模式。只要其他项目已经下载过,就不会上网下载,但依然会拷贝到项目下的node_modules/路径。另外,yarn的运行速度得到了显著的提升,整个安装时间也变得更少。所以推荐使用yarn管理项目依赖。

仓库

maven有中央仓库,也可以创建私服;npm,yarn同样都有,可以配置:

npm config set registry http://registry.npmjs.org/
yarn config set registry https://registry.yarnpkg.com/
  • 1
  • 2

***

国内用户可以通过淘宝镜像提高下载速度:

npm config set registry https://registry.npm.taobao.org
yarn config set registry https://registry.npm.taobao.org
  • 1
  • 2

代理

如果上网需要代理的话,可以在~/.bashrc加入如下内容:

######################
# User Variables (Edit These!)
######################
username="myusername"
password="mypassword" proxy="mycompany:8080" ###################### # Environement Variables # (npm does use these variables, and they are vital to lots of applications) ###################### export HTTPS_PROXY="http://$username:$password@$proxy" export HTTP_PROXY="http://$username:$password@$proxy" export http_proxy="http://$username:$password@$proxy" export https_proxy="http://$username:$password@$proxy" export all_proxy="http://$username:$password@$proxy" export ftp_proxy="http://$username:$password@$proxy" export dns_proxy="http://$username:$password@$proxy" export rsync_proxy="http://$username:$password@$proxy" export no_proxy="127.0.0.10/8, localhost, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16" ###################### # npm Settings ###################### npm config set registry http://registry.npmjs.org/ npm config set proxy "http://$username:$password@$proxy" npm config set https-proxy "http://$username:$password@$proxy" npm config set strict-ssl false echo "registry=http://registry.npmjs.org/" > ~/.npmrc echo "proxy=http://$username:$password@$proxy" >> ~/.npmrc echo "strict-ssl=false" >> ~/.npmrc echo "http-proxy=http://$username:$password@$proxy" >> ~/.npmrc echo "http_proxy=http://$username:$password@$proxy" >> ~/.npmrc echo "https_proxy=http://$username:$password@$proxy" >> ~/.npmrc echo "https-proxy=http://$username:$password@$proxy" >> ~/.npmrc ###################### # yarn Settings ###################### yarn config set registry https://registry.yarnpkg.com/ yarn config set proxy "http://$username:$password@$proxy" yarn config set https-proxy "http://$username:$password@$proxy" yarn config set strict-ssl false
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

脚手架

脚手架可以简化开发,创建工程框架。比如maven可以使用archetype:generate来创建基于maven约定的java工程。

脚手架创建的项目,一般包含以下内容: 
1. 编译脚本、依赖定义 
2. 源代码路径及样例 
3. 单元测试路径及样例 
4. 资源路径 
5. 环境配置(开发环境、生产环境、测试环境) 
6. 编译目标路径(编译后生成)

Angular脚手架

Angular CLIAngular官方提供的命令行工具,可以帮助我们创建项目、编译、测试、运行,就像Java界的Maven,另外还可以创建组件、管道、指令、服务、模块、类、接口、枚举。。。

可以用npm安装Angular CLI

npm install --global @angular/cli
  • 1

创建Angular项目:

ng new <project_name>
  • 1

脚手架会帮我们创建以下文件:

|-- package.json                   # 编译脚本、依赖包管理,类似maven的pom.xml。
|-- src                            # 原代码,类似maven的src/main/java
|   |-- app                        # 该应用的模块路径,angular支持模块化!
|   |   |-- app.component.css # 组件样式(作用域只在该组件内部有效) | | |-- app.component.html # 组件模板(视图) | | |-- app.component.spec.ts # 组件单元测试 | | |-- app.component.ts # 组件控制代码(控制器) | | |-- app.module.ts # 模块管理代码 | |-- assets # 资源文件夹,类似maven的src/main/resources | |-- environments | | |-- environment.prod.ts # 生产环境配置 | | `-- environment.ts # 开发环境配置 | |-- favicon.ico # 网页的图标 | |-- index.html # 网页的HTML,使用根组件(一般无需修改) | |-- main.ts # 入口代码,引导根模块(一般无需修改) | |-- styles.css # 全局样式 | |-- test.ts # 单元测试入口(一般无需修改) | |-- ... |-- tsconfig.json # typescript配置,比如开发使用的ES版本,编译生成的目标ES版本(默认是ES5,即目前广泛的javascript,一般无需修改) |-- tslint.json # typescript的语法规则,方便IDE检查(一般无需修改) |-- node_modules # 项目的依赖包仓库,相当于maven的本地仓库 |-- dist # 编译时才生成的目标文件夹(拷贝里面内容到Web服务器即可使用),相当于maven工程下的target目录 |-- .gitignore # git ignore(一般无需修改,node_modules和dist以默认排除) ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

依赖管理

当我们需要更新项目依赖时,可以修改package.json文件,然后运行yarn install。它会解析package.json并下载还没有的依赖。这种方式跟maven完全一样。

添加/删除依赖

还可以用命令行来添加/删除依赖:

yarn add/remove <package_name>[@<version>] [--dev/-D]
  • 1

[]表示可选的,不写为最新版本。命令执行后会自动更新package.json文件。--dev-D表示包只是开发时候需要,最终产品打包是不包含的,类似与Maven中的provided scope

开发阶段:运行

对于前后端分离的应用,前端开发与后端独立开,前端应用在没有启动后端服务器的情况下也应该能够运行。

Angular CLI提供支持,如下:

ng serve [--host 0.0.0.0] [--port 4200]
  • 1

[]表示可选的,不写端口号默认为4200。打开浏览器,输入localhost:4200可以看到你开发的网页。

代码更新检测

代码文件更新不需要重启服务,当文件内容变化时,网页会自动刷新,开发者可以看到更新后的页面。

Mock 后端服务

在后端服务还没有准备好之前,当前端需要向后端服务发出请求(GET/POST/PUT/DELETE),让后端更新数据,并且返回给前端时,可以造个假的。

可以安装一个json-server

npm install --global json-server
  • 1

写个json文件,把假数据填上去。启动json服务:

json-server <your_mock_data.json> [--port 3000]
  • 1

就可以作为服务器接受客户端的RESTful请求(GET/POST/PUT/DELETE)了。

单元测试

mvn testAngular CLI可以一键运行所有单元测试:

ng test
  • 1

编译成目标文件

mvn compileAngular CLI可以一键运行编译导出目标文件(默认为ES5,即传统的javascript):

ng build [-prod]
  • 1

可选参数-prod表示生产环境,输出目标会小很多。输出目标为dist文件夹:

$ ls -l dist
total 413
-rw-r--r-- 1 weliu 1049089 3293 Jan 15 08:50 3rdpartylicenses.txt -rw-r--r-- 1 weliu 1049089 5430 Jan 15 08:50 favicon.ico -rw-r--r-- 1 weliu 1049089 597 Jan 15 08:50 index.html -rw-r--r-- 1 weliu 1049089 1445 Jan 15 08:50 inline.08a75f8119356113a22d.bundle.js -rw-r--r-- 1 weliu 1049089 341557 Jan 15 08:50 main.e25b64f979f240da775b.bundle.js -rw-r--r-- 1 weliu 1049089 61268 Jan 15 08:50 polyfills.65fe1626e31e03d17f8e.bundle.js -rw-r--r-- 1 weliu 1049089 0 Jan 15 08:50 styles.d41d8cd98f00b204e980.bundle.css
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

不如maven compile的地方,是ng build就只做编译,在编译前也不会先去下载未缓存的依赖包,因此完整的编译前需要手动调用yarn install

部署

将编译生成的dist文件夹中的所有文件放在Web服务器即可。

也可以与服务端代码一起编译,打成一个包,方便部署。

与Java后端一起部署(使用Maven)

对于使用Spring Boot的后端Java代码,只提供RESTful的数据服务,可以打包成一个独立可执行的jar/war包:

$ cd back-end
$ mvn clean package
...
BUILD SUCCESS
...$ ls target/
...
my-web-server.war
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

目前这个war包还只是一个提供RESTful的数据服务器,还没有网页界面。

可以写个脚本把前端编译后dist中的内容,通过jar命令打包进上面的war包(或者jar包),脚本很简单,如下:

$ cat add_to_war.sh
cd dist/
jar uf ../../back-end/target/my-web-server.war *
  • 1
  • 2
  • 3

这样就war包就带有网页界面了,可以放在Tomcat服务器下部署,或者直接启动(Spring Boot默认会内嵌Tomcat服务器):

java -jar back-end/target/my-web-server.war
  • 1

以上过程,可以写一个总的编译脚本build.sh,一键编译整个前后端应用:

# build back-end by maven or gradle
cd back-end mvn clean package # or: gradle clean build # build back-end by yarn and Angular CLI cd ../front-end yarn install -prod ng build -prod # add to war by jar command cd dist/ jar uf ../../back-end/target/my-web-server.war *
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

与Java后端一起部署(使用Gradle)

如果使用Gradle编译打包整个前后端应用,就更简单,因为已经有Gradle插件com.moowork.node直接支持。

在前端Angular项目(比如名为front-end)中,加入build.gradle文件,内容如下:

plugins {id "com.moowork.node" version "0.13"
}apply plugin: 'java'// configure gradle-node-plugin
node {version = '6.5.0'npmVersion = '3.10.7' // If true, it will download node using above parameters. // If false, it will try to use globally installed node. download = false // true workDir = file("${project.projectDir}/node") } task compileTypeScript(type: NpmTask) { // install the express package only args = ['run-script', "tsc"] } // clean node/node_modules/dist task npmClean(type: Delete, group: 'node') { final def webDir = "${project.projectDir}" //delete "${webDir}/node" //delete "${webDir}/node_modules" delete "${webDir}/dist" } clean.dependsOn(npmClean) task npmStart(type: NpmTask) { args = ['start'] group = "node" dependsOn("npmInstall") } task npmBuild(type: NpmTask) { args = ['run', 'build'] group = "node" dependsOn("npmInstall") } jar { dependsOn("npmBuild") from(fileTree("dist")) { into "META-INF/resources" } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

在前端Angular项目的根目录中直接执行:

gradle build
  • 1

就可以编译、打包,在Gradle约定的输出目录build/libs/下生成目标jar文件,包含所有Web资源。

front-end
|   build
|   |-- libs
|   |   |-- front-end-0.0.1.jar
  • 1
  • 2
  • 3
  • 4

在后端Java项目back-end中的build.gradle中加入对前端Angular项目的依赖即可。

dependencies {compile project(":front-end")...
  • 1
  • 2
  • 3

为了一键编译、打包整个前后端工程,可以在前后端项目的父目录中加入build.gradle:

task wrapper(type: Wrapper) { gradleVersion = '3.0' }
  • 1
  • 2
  • 3

settings.gradle

rootProject.name = 'my-web-product'
include 'front-end'
include 'back-end'
  • 1
  • 2
  • 3

在此根目录中,可以一键直接执行:

gradle build
  • 1

这样编译、打包整个前后端工程,在后端项目中生成最终包含Web资源的文件:

my-web-product
|   back-end
|   |   build
|   |   |-- libs
|   |   |   |-- my-web-product-0.0.1.war
  • 1
  • 2
  • 3
  • 4
  • 5

可以看到,就像mavengradle一样,Angular CLI可以帮我们创建脚手架、编译、测试、运行,但她的能力可远不只这些,在开发过程中依然是个好助理,比如可以帮我们创建:组件、服务、管道、指令、模块等等。

组件

组件是一个独立的、可复用的、可组合的UI控件,网页界面就是一系列组件的有机结合。

组件由组件名、视图、控制器组成。

组件相当于面向对象中的“类”,组件实例相当于“对象”。在Angular中,组件就是一个装饰了@Component注解的类。

脚手架创建组件

下面语句创建一个名为hello的组件(同时自动将组件注册到模块app.module.ts中,这样同模块的其它组件才可以使用):

ng g[enerate] c[omponent] hello [--inline-template] [--inline-style] [--spec false]
  • 1

[]为可选,默认情况下生成下面几个文件:

src
|   app
|   |-- hello
|   |   |-- hello.component.css      # 组件样式(作用域只在该组件内部有效)
|   |   |-- hello.component.html # 组件模板(视图) | | |-- hello.component.spec.ts # 组件单元测试 | | |-- hello.component.ts # 组件控制代码(控制器)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

嫌文件太多,也可以把HTML模板和CSS都内联进TypeScript,并且不创建单元测试:

src
|   app
|   |-- hello
|   |   |-- hello.component.ts       # 组件全部代码:控制器、视图、样式
  • 1
  • 2
  • 3
  • 4

内联了模板、CSS的文件hello.component.ts长这个样子:

import { Component, OnInit } from '@angular/core';@Component({selector: 'app-hello',   // 组件选择器(组件名)template: `              // 组件模板(视图)<p>hello works!</p>`,styles: []               // 样式CSS(作用域只在该组件内部有效) }) export class HelloComponent implements OnInit { // 组件控制代码(控制器) constructor() { } ngOnInit() { } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

可以在模块内其它组件HTML模板中使用该组件:

<app-hello></app-hello>
  • 1

服务

前端与后端交互的代码逻辑,在Angular中一般设计成一个服务。服务是一个可以依赖注入的(非常像Spring),容器管理的类。

Angular CLI可以帮我们生成一个服务的代码,下面的命令在src/app/services/目录下创建一个名为job的服务(同时自动将组件注册到模块app.module.ts中,这样同模块的其它组件才可以使用):

ng g[enerate] s[ervice] services/job [--spec false]
  • 1

创建的文件为:src/app/services/job.service.ts。添加代码后可以与后端进行交互(GET/POST/PUT/DELETE)。

import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
import { Observable } from 'rxjs/Observable'; import { Server } from '../model/server'; import { JobDetail } from '../model/job.detail'; @Injectable() export class JobService { private readonly headers = new Headers({ 'Content-Type': 'application/json' }); constructor(private http: Http) {} jobs(host: string, port: number): Observable<JobDetail[]> { return this.get('jobs', { host: host, port: port }); } runJob(job: string[], servers: Server[]) { if (job.length === 0 || servers.length === 0) { return; } const serverHostPorts = servers.map(server => `${server.host}:${server.port}`); console.log(`run job ${job} on servers ${serverHostPorts}`); this.post('run', { job: job, hostPorts: serverHostPorts }).subscribe(); } private get(action: string, params: any = {}): Observable<any> { return this.http.get(`api/${action}`, { headers: this.headers, params: params }) .map(res => res.json()); } private post(action: string, data: any = {}, params: any = {}): Observable<any> { return this.http.post(`api/${action}`, data, { headers: this.headers, params: params }); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

虽然Angular CLI都会给服务类修饰@Injectable注解,但并不是服务的标识,也不是必要的。它的作用是让Angular框架能够向该类注入其它服务,比如构造函数中Http服务就是由Angular框架通过依赖注入进来的。这种机制与Spring非常相似。

Angular是基于rxjs的,操作http会得到一个可观察对象Observerable<any>,异步编程、事件处理都非常简单。熟悉RxJava的同学觉得非常亲切。

Angular是一个类似于Spring的框架,其容器管理服务和组件,所有服务都是可以依赖注入的(只提供构造器注入,这也是不可变成员变量的最佳实践)。所有,在组件或其它服务中使用服务就非常简单,只要在构造函数把服务传进来即可,下面演示了servers组件使用上面定义的job服务:

@Component({selector: 'app-servers',templateUrl: './servers.component.html', styleUrls: ['./servers.component.css'] }) export class ServersComponent { jobs: JobDetail[] = []; constructor(private jobService: JobService) { jobService.jobs().subscribe(jobs => this.jobs = jobs); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

下面演示rxjs的好处,比如我们想每隔5秒,异步地去服务器请求数据,拿到后刷新jobs控件,一句话搞定:

constructor(private jobService: JobService) { Observable.interval(5000).subscribe(evt => jobService.jobs().subscribe(jobs => this.jobs = jobs)); }
  • 1
  • 2
  • 3
  • 4

管道

先看个例子来理解管道,比如我们在控制器typescript文件中有一个成员变量(字符串数组类型):

command: string[] = ['java', '-jar', 'hello.jar'];
  • 1

在视图html模板中显示:

<div>{{ command }} </div>
  • 1
  • 2
  • 3

会看到显示的内容是:

java, -jar, hello.jar
  • 1

这是string[]类型的toString()方法输出的,但逗号很不好看,希望它输出是这样的:

java -jar hello.jar
  • 1

有两种办法,第一种是直接在html中({{ }}里面可以是一个表达式):

<div>{{ command.join(' ') }} </div>
  • 1
  • 2
  • 3

第二种办法可以创建一个名叫join的管道,类型Linux管道一样使用:

<div>{{ command | join: ' ') }} </div>
  • 1
  • 2
  • 3

Angular CLI有创建管道的方法,下面的命令在src/app/pipes目录下创建了一个叫join的管道(同时自动将组件注册到模块app.module.ts中,这样同模块的其它组件才可以使用):

ng g[enerate] p[ipe] pipes/join [--spec false]
  • 1

由注解@Pipe修饰的类称为管道类,在生成的src/app/pipes/join.pipe.ts中,我们在加入transform方法中加入join的逻辑。

import { Pipe, PipeTransform } from '@angular/core';@Pipe({name: 'join'   // 管道的名字以供HTML模板使用
})
export class JoinPipe implements PipeTransform { transform(input: any, character: string = ''): string { if (!Array.isArray(input)) { return input; } return input.join(character); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

内置管道

当然,Angular提供的内置管道非常好用,看下面的代码:

class Server {host: string;port: number; toString(): string { // 作用完全等同Java的toString方法 return `${host}:${port}`; // 与Kotlin一样也支持模板字符串语法 } } myServer: Server = { // 用json直接赋值,比Java方便不少吧 host: "127.0.0.1", // 如果变量名或者赋值类型的值写错了,类型系统会提示出错 port: 8080 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

HTML模板:

<div>{{ myServer }}</div>
  • 1

显示结果为:

127.0.0.1:8080
  • 1

如果想要把下面的对象myServer按照json格式打印出来,可以用json管道:

<div>{{ myServer | json }}</div>
  • 1

显示结果为:

{"host": "127.0.0.1","port": 8080 }
  • 1
  • 2
  • 3
  • 4

如果上面的json是服务端发送过来的,那么结果是一个rxjs可观察对象Observable<Server>

myServer$: Observable<Server> = http.get('api/server').map(res => res.json());
  • 1

Observable类型的变量名以$结尾,是Angular的一种编程习惯,因为rxjs使用频率太高,这是为了区分普通对象和可观察对象。

可以不需要在代码中手动订阅,也不需要考虑什么时候去解除订阅,在HTML模板中用async管道,

<div>{{ myServer$ | async }}</div>
  • 1

当可观察对象有新值(onNext)时会在网页中更新,显示结果为:

127.0.0.1:8080
  • 1

就像Linux中的管道一样,Angular的管道也可以级联,上面的结果很容易以json格式显示出来:

<div>{{ myServer$ | async | json }}</div>
  • 1

显示结果为:

{"host": "127.0.0.1","port": 8080 }
  • 1
  • 2
  • 3
  • 4

模块

可以看到,Angular CLI可以帮我们创建组件、服务、管道、指令等,非常方便,它们都有共同的特点,就是都会更改模块定义文件(app.module.ts)。

那么,什么是模块?

类似于Java 9OSGi的模块化,Angular应用天生就是模块化,概念都是差不多的。模块,就是在类和包之上在做封装,通常把协同完成某个功能的一组组件、服务作为一个整体,就是一个模块。打个比方,如果把模块想象成一个班级,那么组件、服务就是班上的同学。

模块具有封装性和隔离性,模块外部无法访问模块内部的组件、服务,除非导入该模块。这一点,用过OSGiEclipse RCP很熟悉,一个模块相对于一个Eclipse插件。如果想在一个插件中使用另一个插件的类,常用的做法是在插件声明文件MANIFEST.MF中声明为Require-Bundle(当然Eclipse不只这一种方法,比如还可以动态导入、或只import包名让OSGi容器自动去匹配插件,目前Angular模块化还做不到这一点)。

Angular CLI脚手架创建的src/app/app.module.ts,定义了一个由注解@NgModule装饰的类(模块类),用于管理该模块。这个文件就好比Eclipse插件中的MANIFEST.MF。一个模块类的代码如下:

import { BrowserModule } from '@angular/platform-browser';@NgModule({                   // 模块类的标识由该注解决定declarations: [             // 声明组件、管道、指令,类型由具体类的注解来区分,用Angular CLI创建时会自动填入AppComponent, MyPipe, MyDirective ...],imports: [                  // imports指定要导入的模块,这样才可以使用其它模块内的组件、指令、管道、服务BrowserModule, ...],providers: [                // 声明服务,只有声明的服务才会被`Angular`框架创建出来,才能注入到其它服务或组件MyService, ...            // 用Angular CLI创建时会自动填入],bootstrap: [AppComponent]   // 引导组件
})
export class AppModule { }    // 模块类定义
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

一个Angular应用中可以有多个模块,用Angular CLI可以很容易创建一个模块:

ng g module your-new-module-name
  • 1

Angular CLI创建TypeScript

创建普通类:

ng g class my-new-class
  • 1

创建接口:

ng g interface my-new-interface
  • 1

创建枚举:

ng g enum my-new-enum
  • 1

IDE

免费版本推荐使用微软的Visual Studio Code (VSCode), 很好用,但有条件一定要买付费的IDEJetBrainWebStorm。原因就跟Java IDE的选择一样,要免费的Eclipse,还是商业使用需付费的IntelliJ IDEA,看你或你的公司是不是土豪。

笔者是穷屌丝,使用VSCode,编写Angular代码,推荐安装下面的插件:

  1. Angular 5 Snippets:Angular开发必备,这里我使用的是Angular 5
  2. TSLint:TypeScript基于最佳实践的编程规范检测插件(类似于JavaCheckStyle),以红线实时提示你的不规范代码。
  3. TypeScript Importer:在编写TypeScript代码时,当你使用一个新的类,自动插入import语句。

Typescript类型系统非常好的地方是IDE的提示非常好,比如能提示出类有哪些方法、哪些属性,再加上语法和方法与Java太像,使用起来非常自然、亲切。

总结

读到这里,相信你已经有了Angular的开发环境,并且对一些Angular的概念有了初步理解,能够与服务端一起编译并部署到Web服务器上。

也许你会问我,有那么多Web前端框架,为什么偏爱Angular

选择Angular的原因

笔者作为一个Java背景的软件开发人员,选择Angular的原因有:

使用TypeScript编程

TypeScript,其实并不是一种新语言,她仍然还是JavaScript,是一种带有类型系统的、面向对象版本的JavaScript,是ES6/7/8+的超集:

  1. 语法类似Java/Kotlin,很多语言特性、关键字、类方法名都是一样的;
  2. 类型系统可以在编译期做检查,避免敲错字;
  3. 类型系统可以帮助IDE分析代码,代码跳转、引用分析、出错实时提醒等;
  4. 类型系统可以提高代码的可读性、可维护性、类型安全性,调用方法时可以避免传入不期望的类型;
  5. TypeScriptES6+的超集,是ES6规范的实现,在未来的浏览器很可能直接支持;
  6. TypeScript可以直接编译成ES5运行于旧浏览器,在现有版本的Angular是默认编译目标,无需引入任何编译依赖和配置;
  7. TypeScript与其编译出的ES5 javascript代码是一一对应的,很多时候就是类型擦除,无需额外库,不像Kotlin.js那么重。
  8. 拼爹时代,这点还是要考虑的:微软的TypeScript,加上谷歌的Angular,非常看好它的前景。
  9. JavaScript编写的库可以在TypeScript使用,缺乏类型声明部分,社区以提供大量第三方js库的类型定义,一般不需要自己做,当然,想自定义个类型也不难。

如果你是Java程序员,应该会赞成这句话:“TypeScript一点都不难,JavaScript才叫难!”。

当然如果你真的不习惯写类型,那不写也可以,因为TypeScriptES6+的超集,ES6+的代码在TypeScript完全合法,不过就没有了编译时类型检查,IDE也不会帮你跳转和引用分析,也不会做方法提示,你能接受缺乏类型安全机制的痛苦吗?我不能!

很像Spring Boot框架

Angular框架很像Spring Boot框架(都无需额外配置),有组件、服务、依赖注入、基于注解的配置,容器管理组件、服务的生命周期等特性;

基于rxjs

rxjs可以方便编写异步响应式代码、处理事件总线、大量可组合的操作符、等等(其实就是流行的RxJavaTypeScript版本)。

模块化

模块化对于构建大型复杂的Web系统来说尤为重要。

所以

对于JavaKotlin等静态强类型语言背景的开发人员来说,Angular学习门槛较低,因为很多特性、概念都太Java了。

而对于JavaScriptPython等动态语言背景的开发人员,入手React, Vue可能更容易,因为它们都是基于ES6的无类型系统。

——- 本博客所有内容均为原创,转载请注明作者和出处 ——-

作者:刘文哲

联系方式:liuwenzhe2008@qq.com

博客:http://blog.csdn.net/liuwenzhe2008

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuwenzhe2008/article/details/79125406

转载于:https://www.cnblogs.com/w-xibao/p/9246312.html

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 【repost】前端学习总结(二十三)——前端框架天下三分:Angular React 和 Vue的比较...

    目录(?)[] 前端这几年的技术发展很快&#xff0c;细分下来&#xff0c;主要可以分成四个方面&#xff1a; 1.开发语言技术&#xff0c;主要是ES6&7&#xff0c;coffeescript&#xff0c;typescript等&#xff1b; 2.开发框架&#xff0c;如Angular&#xff0c;React,Vue.j…...

    2024/4/24 8:22:33
  2. angularjs directive 实例 详解

    angularjs directive 实例 详解 张映 发表于 2014-03-13 前面提到了angularjs的factory,service,provider&#xff0c;这个可以理解成php的model&#xff0c;这种model是不带html的&#xff0c;今天所说的directive,也可以理解成php的model&#xff0c;也可以理解成插件&a…...

    2024/4/23 20:26:39
  3. PHP 面试知识点整理归纳

    全文已整理补充完毕&#xff0c;以后还会继续更新文章里面的错误&#xff0c;以及补充尚不完善的问题。 该篇文章是针对Github上wudi/PHP-Interview-Best-Practices-in-China资源的答案个人整理 lz也是初学者&#xff0c;以下知识点均为自己整理且保持不断更新&#xff0c;也希…...

    2024/4/23 9:05:43
  4. 利用基于angularjs的angular-file-upload.min.js控件实现上传文件

    参考博客: https://blog.csdn.net/zcl_love_wx/article/details/51692819 相关网址: 官网&#xff1a;http://www.bootcdn.cn/angular-file-upload/readme/ API &#xff1a; https://github.com/nervgh/angular-file-upload/wiki/Module-API https://segmentfault.…...

    2024/5/2 22:56:28
  5. 前端框架天下三分:Angular React 和 Vue的比较

    前端这几年的技术发展很快&#xff0c;细分下来&#xff0c;主要可以分成四个方面&#xff1a; 1.开发语言技术&#xff0c;主要是ES6&7&#xff0c;coffeescript&#xff0c;typescript等&#xff1b; 2.开发框架&#xff0c;如Angular&#xff0c;React,Vue.js&#xff…...

    2024/4/23 13:21:03
  6. angular依赖注入_依赖注入:Angular vs. RequireJS

    angular依赖注入如果您以前曾经构建过大型JavaScript应用程序&#xff0c;那么您将面临管理组件依赖项的任务。 您可以将组件视为功能块。 它可以是函数&#xff0c;对象或实例。 该块选择公开一个或多个公共方法。 它还可以选择隐藏非公共功能。 在本文中&#xff0c;我们将研…...

    2024/4/27 3:03:25
  7. angular、vue、react的区别

    前端这几年的技术发展很快&#xff0c;细分下来&#xff0c;主要可以分成四个方面&#xff1a; 1.开发语言技术&#xff0c;主要是ES6&7&#xff0c;coffeescript&#xff0c;typescript等&#xff1b; 2.开发框架&#xff0c;如Angular&#xff0c;React,Vue.js&#xff0…...

    2024/4/23 13:41:19
  8. angularjs中post请求进行跨域

    post请求进行跨域angularjs内置封装了类ajax的网络服务$http,所以实现了依赖外部插件来完成完整的前后端分离方案$scope.main {getData: function () {$http({method: POST,url: http://localhost:8000,headers: {Content-Type : application/x-www-form-urlencoded},data: {m…...

    2024/5/3 4:20:45
  9. angular用$http请求数据

    项目中用到$http请求数据接口像jQuery里的$ajax一样分为post请求和get请求. get请求: $http({ url:url1, //接口地址method: get }).success(function(data){ //请求成功console.log("成功"); }).error(function…...

    2024/5/3 6:36:38
  10. angular 接口请求不到数据的问题

    最近在用ng5升级ext的老项目&#xff0c;发现post请求一直请求不到数据&#xff0c;最终发现原因是数据格式的问题。 服务器接口接收的是form表单格式&#xff0c;而前端post请求发送的是json数据格式。比如下面这个请求&#xff1a; this.http.post(${this.uri}/data/list.jso…...

    2024/4/26 2:34:30
  11. Angular 请求数据

    Angular 请求数据 get post 以及 jsonp 请求数据 引入 HttpModule 、JsonpModule 普通的 HTTP 调用并不需要用到 JsonpModule&#xff0c;不过稍后我们就会延演示对 JSONP 的支持&#xff0c;所以现在就加载它&#xff0c;免得再回来浪费时间。 引入模块 import { HttpClientJs…...

    2024/5/2 22:04:54
  12. 【前端】10. Angular 中的数据交互(get jsonp post )

    参考视频&#xff1a;https://www.bilibili.com/video/av50917863?p12 Angular8视频教程-IT营配套笔记如下&#xff08;参考自大地老师&#xff09;&#xff1a; 一、Angular get 请求数据 Angular5.x 以后 get、post 和和服务器交互使用的是 HttpClientModule 模块。 1、…...

    2024/5/2 6:55:29
  13. Angular中页面传参获取参数

    今天使用html传参数&#xff0c;始终获取不到参数值。研究了半天&#xff0c;终于解决&#xff0c;以下是angular获取页面传参参数方法在angular中有一项服务为$location&#xff0c;使用这项服务可以获取页面参数&#xff0c;$location的方法不止这一个&#xff0c;还可以获取…...

    2024/5/2 2:39:52
  14. AngularJs 自定义指令中的Scope属性

    1.应用场景 了解AngularJs 自定义指令中的Scope属性的用法. 2.学习/操作 一、概念说明   可以是true、 false 、哈希对象 {}   1、true     新创建了一个作用域&#xff0c;且继承了父作用域&#xff1b;在初始化的时候&#xff0c;用了父作用域的属性和方法去填充我们…...

    2024/5/2 3:32:47
  15. Angular8 发布与订阅 解决子组件与父组件传值问题

    本文主要作用是解决子组件向父组件传值&#xff0c;Output()方法不适用得情况&#xff0c;也可以作为主流传值手段使用。 其他子父组件传值也可以通过浏览器的储存机制来处理&#xff0c;例如&#xff1a;sessionStorage, localstorage等来解决&#xff0c;不过比起订阅模式来说…...

    2024/5/1 22:59:24
  16. 浅聊angular2中通信方式

    前言&#xff1a; 在软件开发工程中&#xff0c;随着应用规模的不断扩大&#xff0c;必然需要进行逻辑分离。在 Web 开发中&#xff0c;组件化和模块化的观念已经被越来越多的人所熟知&#xff0c;从而编写出更高质量的代码。 同时&#xff0c;随着实体职责的分离&#xff0c;我…...

    2024/4/26 5:28:15
  17. angular2--不同页面间发起通知 sfnBroadCast

    例如&#xff1a;当我退出登录的时候&#xff0c;需要通知用户中心 一、在需要发起通知的页面&#xff1a; 1、引入 import { EventServices } from ../../../services/event.services;2、在构造函数中加入&#xff1a; constructor(private eventBus: EventServices&#…...

    2024/4/26 19:12:34
  18. Angular2学习笔记——在子组件中拿到路由参数

    原文链接&#xff1a;http://www.cnblogs.com/dojo-lzz/p/5883408.html 工作中碰到的问题&#xff0c;特此记录一下。 Angular2中允许我们以path\:id\childPath的形式来定义路由&#xff0c;比如&#xff1a; export const appRoutes: RouterConfig [{path: app/:id, componen…...

    2024/5/3 0:17:38
  19. angular2语法总结

    1、ngStyle 基本用法 <div [ngStyle]"{background-color:green}"></<div> 判断添加<div [ngStyle]"{background-color:username zxc ? green : red }"></<div> 2、ngClass第一个参数为类名称&#xff0c;第二个参数为boo…...

    2024/5/2 2:50:52
  20. Angular day2 组件相关 + pipe

    一.循环 ngFor //在html文件中 <div>{{title}}</div> <ul><li *ngFor"let item of menus"><a href"#">{{ item.title }}</a></li> </ul>//在对应html文件的component.ts文件中 interface TopMenu {title…...

    2024/5/2 1:51:32

最新文章

  1. Linux学习系列文件管理之输出与重定向

    在 Linux 中有三个经常用到的输入输出流&#xff0c;他们分别是&#xff1a; 标准输入&#xff08;stdin&#xff09;标准输出&#xff08;stdout&#xff09;标准错误&#xff08;stderr&#xff09; 在 Linux 系统中&#xff0c;系统保留了 0&#xff08;标准输入&#xff…...

    2024/5/3 7:16:00
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. Web大并发集群部署之集群介绍

    一、传统web访问模型 传统web访问模型完成一次请求的步骤 1&#xff09;用户发起请求 2&#xff09;服务器接受请求 3&#xff09;服务器处理请求&#xff08;压力最大&#xff09; 4&#xff09;服务器响应请求 传统模型缺点 单点故障&#xff1b; 单台服务器资源有限&…...

    2024/5/1 13:15:58
  4. 电脑上音频太多,播放速度又不一致,如何批量调节音频播放速度?

    批量调节音频速度是现代音频处理中的一个重要环节&#xff0c;尤其在音乐制作、电影剪辑、有声书制作等领域&#xff0c;它能够帮助制作者快速高效地调整音频的播放速度&#xff0c;从而满足特定的制作需求。本文将详细介绍批量调节音频速度的方法、技巧和注意事项&#xff0c;…...

    2024/5/2 23:06:54
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/1 17:30:59
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/2 16:16:39
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/2 9:28:15
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/2 15:04:34
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/30 22:21:04
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/1 4:32:01
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/2 9:07:46
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57