[Schematics] 1. Copy and Manipulate Template
1. Create a src/my-component/files/src/app
directory to hold your templates.
mkdir -p src/my-component/files/src/app
2. Create an app.component.ts
file in src/my-component/files/src/app
and put the following code in it:
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { name = '<%= name %>'; }
The <%= name %>
variable is an option you’ll pass in when running this Schematic. Create an app.component.html
file with some HTML that reads the name variable.
3. Add template as well:
<div style="text-align:center"> <h1> Hello, {{ name }} </h1> </div> <router-outlet></router-outlet>
4. Now what we want is let user to give the 'name' thought prompt, In order to define the name
prompt, create a schema.json
file in the src/my-component
directory.
{ "$schema": "http://json-schema.org/schema", "id": "SchematicsMyComponent", "title": "My Component Schema", "type": "object", "properties": { "name": { "type": "string", "description": "Your Name", "x-prompt": "What is your name?" } }, "required": ["name"] }
Then update src/collection.json
to reference this file in a schema
property.
{ "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { "my-component": { "description": "A blank schematic.", "factory": "./my-component/index#myComponent", "schema": "./my-component/schema.json" } } }
5. Then update src/my-component/index.ts
so you can get your generated project’s path, and copy templates.
import { apply, MergeStrategy, mergeWith, move, Rule, SchematicContext, template, Tree, url, FileEnty, forEach } from '@angular-devkit/schematics'; import { join, normalize } from 'path'; import { getWorkspace } from '@schematics/angular/utility/config'; export function setupOptions(host: Tree, options: any): Tree { const workspace = getWorkspace(host); if (!options.project) { options.project = Object.keys(workspace.projects)[0]; } const project = workspace.projects[options.project]; options.path = join(normalize(project.root), 'src'); return host; } export function myComponent(_options: any): Rule { return (tree: Tree, _context: SchematicContext) => { setupOptions(tree, _options); const movePath = normalize(_options.path + '/'); const templateSource = apply(url('./files/src'), [ template({..._options}), move(movePath), // fix for https://github.com/angular/angular-cli/issues/11337 forEach((fileEntry: FileEntry) => { if (tree.exists(fileEntry.path)) { tree.overwrite(fileEntry.path, fileEntry.content); } return fileEntry; }), ]); const rule = mergeWith(templateSource, MergeStrategy.Overwrite); return rule(tree, _context); }; }
We can use this as a template when we want to add some template into the schematics.
6. Test with real application:
ng new my-test-app --routing --style css cd my-test-app npm link ../my-component ng g my-component:my-component
When I tried this, it prompted me:
$ ng g my-component:my-component ? What is your name? Matt UPDATE src/app/app.component.html (109 bytes) UPDATE src/app/app.component.ts (207 bytes)
7. Support for ng add with Angular CLI:
A slick feature of Angular CLI is its ng add
command. You can use it to invoke schematics and add features like PWA support and Angular Material to your projects. For example:
ng add @angular/pwa
ng add @angular/material
You can support for ng add $your-schematic
too! Open my-component/src/collection.json
and add a new ng-add
schematic.
{ "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { "my-component": { "description": "A blank schematic.", "factory": "./my-component/index#myComponent", "schema": "./my-component/schema.json" }, "ng-add": { "factory": "./ng-add/index", "description": "Add schematic", "schema": "./my-component/schema.json" } } }
Create src/ng-add/index.ts
and add the code necessary for it to invoke the my-component
schematic.
import { chain, Rule, schematic, SchematicContext, Tree, } from '@angular-devkit/schematics'; export default function (options: any): Rule { return (host: Tree, context: SchematicContext) => { return chain([ schematic('my-component', options) ])(host, context); }; }
After build, link to project, then you can run:
ng add my-component
相关文章
- [AWS] Lab: Create a REST API with API Gateway and Lambda with CORS
- [Vue-rx] Pass Template Data Through domStreams in Vue.js and RxJS
- [Vue + TS] Use Dependency Injection in Vue Using @Inject and @Provide Decorators with TypeScript
- [React] Create a Virtualized List with Auto Sizing Cells using react-virtualized and CellMeasurer
- [Angular Directive] Structure directive and <template>
- [Angular 2] Generate and Render Angular 2 Template Elements in a Component
- [CSS] Using single grid-template-area and justify-self to select arrow down icon in select
- [Javascript] Natively Format JavaScript Dates and Times
- [Vue-rx] Pass Template Data Through domStreams in Vue.js and RxJS
- [Angular Directive] Structure directive and <template>
- [Angular 2] Generate and Render Angular 2 Template Elements in a Component
- Linux CentOS 6.x报错解决:错误:Cannot retrieve metalink for repository: epel. Please verify its path and tr
- Numeric tile and other files loaded in Smart Template tile render launch
- Atitit.git的存储结构and 追踪
- 【Henu ACM Round#14 A】Vitaly and Night
- fragment in UI5 Smart Template and directive in Angular
- Building Microservices with Spring Boot and Apache Thrift. Part 2. Swifty services
- Codeforces #250 (Div. 2) C.The Child and Toy
- TCP回放攻击 & DDoS脉冲攻击Hit and Run IoT僵尸网络 在DDoS攻击黑产领域最活跃