详解创建自定义的Angular Schematics


Posted in Javascript onJune 06, 2018

本文对 Angular Schematics 进行了介绍,并创建了一个用于创建自定义 Component 的 Schematics ,然后在 Angular 项目中以它为模板演练了通过 Schematics 添加自定义的 Component 。

1. 什么是 Schematics?

 简单来说,Schematics 是一个项目处理工具,可以帮助我们对 Angular 项目中的内容进行成批的处理。

比如我们在是使用 Angular CLI 的时候,可能使用过诸如 ng g c myComponent 之类的命令来帮助我们创建一个新 Component ,这个命令将各种工作成批完成,添加 Component 代码文件、模板文件、样式文件、添加到 Module 中等等。

现在,我们也可以自己来创建自定义的 Schematics 。在下面的介绍中,我们将创建一个自定义的 Schematics,实现这个类似的功能,我们还提供了命令选项的支持。

对于 Schematics 的介绍,请参考:Schematics — An Introduction

2. 演练创建 Schematics

首先您需要安装  Schematics 的命令行工具。

npm install -g @angular-devkit/schematics-cli

然后,就可以使用这个工具来创建您的第一个 Schematics 了,我们将它命名为 my-first-schema。

schematics blank --name=my-first-schema

这会创建名为 my-frist-schema 的文件夹,在其中已经创建了多个文件,如下所示。

我们使用 blank 为我们后继的工作打好基础。

详解创建自定义的Angular Schematics

 然后,我们定义自己的 Schematics 。

需要将 src 文件夹中的 collection.json 修改成如下内容:

{
 "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
 "schematics": {
 "my-first-schema": {
  "aliases": ["mfs"],
  "factory": "./my-first-schema",
  "description": "my first schematic.",
  "schema": "./my-first-schema/schema.json"
 }
 }
}

$schema => 定义该 collection 架构的 url 地址.

schematics => 这是你的  schematics 定义.

my-first-schema => 以后使用这个  schematics 的 cli 名称.

aliases => 别名.

factory => 定义代码.

Description => 简单的说明.

Schema => 你的 schema 的设置. 这个文件的内容应该如下所示。我们在其中定义了多个自定义的选项,在使用这个 Schematics 的时候,可以通过这些选项来设置生成的内容。

{
 "$schema": "http://json-schema.org/schema",
 "id": "my-first-schema",
 "title": "my1er Schema",
 "type": "object",
 "properties": {
  "name": {
  "type": "string",
  "default": "name"
  },
  "path": {
  "type": "string",
  "default": "app"
  },
  "appRoot": {
  "type": "string"
  },
  "sourceDir": {
  "type": "string",
  "default": "src/app"
  },
  "service": {
  "type": "boolean",
  "default": false,
  "description": "Flag to indicate whether service should be generated.",
  "alias": "vgs"
  }
 }
}

这里可以设置你的 schematics 的命令选项,类似于在使用 g 来创建一个新的组件的时候,您可以使用一个 --change-detection 的选项。

ng g c component-name --change-detection

您还需要为您的选项创建一个接口 schema.ts。

export interface schemaOptions {
 name: string;
 appRoot: string;
 path: string;
 sourceDir: string;
 service: boolean;
}

下面才是我们的核心内容 index.ts 。这里定义我们 schematics 的逻辑实现。

import { chain, mergeWith } from '@angular-devkit/schematics';
import { apply, filter, move, Rule, template, url, branchAndMerge } from '@angular-devkit/schematics';
import { normalize } from '@angular-devkit/core';
import { dasherize, classify} from "@angular-devkit/core/src/utils/strings";
import { schemaOptions } from './schema';

const stringUtils = {dasherize, classify};

function filterTemplates(options: schemaOptions): Rule {
 if (!options.service) {
 return filter(path => !path.match(/\.service\.ts$/) && !path.match(/-item\.ts$/) && !path.match(/\.bak$/));
 }
 return filter(path => !path.match(/\.bak$/));
}

export default function (options: schemaOptions): Rule {
 // TODO: Validate options and throw SchematicsException if validation fails
 options.path = options.path ? normalize(options.path) : options.path;
 
 const templateSource = apply(url('./files'), [
  filterTemplates(options),
  template({
   ...stringUtils,
   ...options
  }),
  move('src/app/my-schema')
  ]);
  
  return chain([
  branchAndMerge(chain([
   mergeWith(templateSource)
  ])),
  ]);

}

Classify is for a little magic in the templates for the schematics.

filterTemplates is a filter for use or add more files.

option.path it's very important you use this option for create the folders and files in the angular app.

templateSource use the cli options and “build” the files into “./files” for create you final template (with the cli options changes)

在 my-first-schema 文件夹中,创建名为 files 的文件夹,添加三个文件:

my-first-schema.component.ts

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

@Component({
 selector: 'my-first-schema-component',
 templateUrl: './my-first-schema.component.html',
 styleUrls: [ './my-first-schema.component.css' ]
})

export class MyFirstSchemaComponent {

 constructor(){
 console.log( '<%= classify(name) %>' );
 }

}

这是一个模板文件,其中可以看到 <%= classify(name) %> 的内容。当你在使用这个 schematics 的时候,classify 将用来获取 options 中的 name 的值。

my-first-schema.component.html

<% if (service) { %>
 <h1>Hola Service</h1>
<% } %>

<% if (!service) { %>
 <h1>Hola no Service</h1>
<% } %>

这里的 service 同样来自 options,我们定义了一个 Boolean 类型的选项。

my-first-schema.component.css,这个文件目前保持为空即可。

回到控制台,在你的项目文件夹中执行 build 命令:npm run build

 定义已经完成。

3. 在 Angular 项目中使用这个 Schematics

下面,我们在其它文件夹中,创建一个新的 Angular 项目,以便使用刚刚创建的这个 Schematics。

ng new test-schematics

进入到这个项目中,使用我们新创建的 schematics。

在其 node-modules 文件夹中创建名为 mfs 的模块文件夹,我们还没有将新创建的 Schematics 上传到 Npm 中,这里我们手工将其复制到新建的 Angular 项目中。

将您前面创建的 schematics 项目中所有的文件(除了 node_modules 文件夹和 package-lock.json 文件之外),复制到这个 mfs 文件夹中,以便使用。

现在,我们可以使用前面创建的这个 schematics 了。

ng g my-first-schema mfs  — service  — name=”Mfs”  — collection mfs

这里设置了 name 和 service 的值。

你应该看到如下的输出:

PS test-schematics> ng g my-first-schema mfs --service --name="Mfs" --collection mfs
  create src/app/my-schema/my-first-schema.component.css (0 bytes)
  create src/app/my-schema/my-first-schema.component.html (33 bytes)
  create src/app/my-schema/my-first-schema.component.ts (320 bytes)
PS test-schematics>

在刚才新建的 Angular 项目 src/app 文件夹中,已经新建了一个名为 my-first-schema 的文件夹,其中包含了三个文件。

打开 my-first-schema.component.ts 文件,可以看到替换之后的内容

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

@Component({
 selector: 'my-first-schema-component',
 templateUrl: './my-first-schema.component.html',
 styleUrls: [ './my-first-schema.component.css' ]
})

export class MyFirstSchemaComponent {

 constructor(){
 console.log( 'Mfs' );
 }

}

而在 my-first-schema.component.html 中,可以看到 --service 的影响。

<h1>Hola Service</h1>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 学习初步 入门教程
Mar 25 Javascript
node.js中的fs.readlinkSync方法使用说明
Dec 17 Javascript
jquery实现图片水平滚动效果代码分享
Aug 26 Javascript
AngularJS 遇到的小坑与技巧小结
Jun 07 Javascript
ES6学习之变量的解构赋值
Feb 12 Javascript
Angular2开发环境搭建教程之VS Code
Dec 15 Javascript
vue.js 底部导航栏 一级路由显示 子路由不显示的解决方法
Mar 09 Javascript
Vue-cli3简单使用(图文步骤)
Apr 30 Javascript
node.js使用http模块创建服务器和客户端完整示例
Feb 10 Javascript
js实现微信聊天界面
Aug 09 Javascript
Node.js web 应用如何封装到Docker容器中
Sep 01 Javascript
编写v-for循环的技巧汇总
Dec 01 Javascript
vue组件实现进度条效果
Jun 06 #Javascript
Express的HTTP重定向到HTTPS的方法
Jun 06 #Javascript
vue组件实现可搜索下拉框扩展
Oct 23 #Javascript
微信小程序实现美团菜单
Jun 06 #Javascript
详解express + mock让前后台并行开发
Jun 06 #Javascript
vue element项目引入icon图标的方法
Jun 06 #Javascript
vue脚手架搭建过程图解
Jun 06 #Javascript
You might like
PHP网上调查系统
2006/10/09 PHP
用ADODB来让PHP操作ACCESS数据库的方法
2006/12/31 PHP
PHP COOKIE设置为浏览器进程
2009/06/21 PHP
解析htaccess伪静态的规则
2013/06/18 PHP
采用memcache在web集群中实现session的同步会话
2014/07/05 PHP
php中rename函数用法分析
2014/11/15 PHP
PHP微信发送推送消息乱码的解决方法
2019/02/28 PHP
thinkPHP框架通过Redis实现增删改查操作的方法详解
2019/05/13 PHP
javascript 面向对象编程基础 多态
2009/08/21 Javascript
extjs表格文本启用选择复制功能具体实现
2013/10/11 Javascript
使用JavaScript实现Java的List功能(实例讲解)
2013/11/07 Javascript
在JavaScript中构建ArrayList示例代码
2014/09/17 Javascript
node.js中的fs.readdir方法使用说明
2014/12/17 Javascript
jQuery实现仿Google首页拖动效果的方法
2015/05/04 Javascript
jquery控制页面部分刷新的方法
2015/06/24 Javascript
详解Bootstrap的aria-label和aria-labelledby应用
2016/01/04 Javascript
JavaScript使ifram跨域相互访问及与PHP通信的实例
2016/03/03 Javascript
javascript中的闭包概念与用法实践分析
2019/07/26 Javascript
vue父子组件通信的高级用法示例
2019/08/29 Javascript
vue中keep-alive,include的缓存问题
2019/11/26 Javascript
Jquery高级应用Deferred对象原理及使用实例
2020/05/28 jQuery
[46:55]Ti4 冒泡赛第二轮 LGD vs C9
2014/07/14 DOTA
[00:57]深扒TI7聊天轮盘语音出处5
2017/05/11 DOTA
python线程锁(thread)学习示例
2013/12/04 Python
Python psutil模块简单使用实例
2015/04/28 Python
python数字图像处理之高级滤波代码详解
2017/11/23 Python
Python迭代器和生成器定义与用法示例
2018/02/10 Python
python验证码识别教程之利用投影法、连通域法分割图片
2018/06/04 Python
Python hmac模块使用实例解析
2019/12/24 Python
巴西宠物商店:Cobasi
2019/04/19 全球购物
广州足迹信息技术有限公司Java软件工程师试题
2014/02/15 面试题
好学生评语大全
2014/05/05 职场文书
爱心捐助活动总结
2015/05/09 职场文书
实习报告怎么写
2019/06/20 职场文书
详解python字符串驻留技术
2021/05/21 Python
叶县这家生产军用电台的兵工厂,人称“四机部”,走出一上将
2022/02/18 无线电