Angular使用cli生成自定義文件、組件的方法
不得不說(shuō),和傳統(tǒng)的復(fù)制黏貼來(lái)創(chuàng)建組件的方法相比,使用angular-cli的腳手架功能來(lái)創(chuàng)建模塊、組件顯得非常高效,不僅僅有了創(chuàng)建了文件,還包含了一些必須的代碼,同時(shí)也將組件導(dǎo)入了最近的模塊,一些重復(fù)性工作就使用cli可以節(jié)省掉。angular提供了豐富的文件類(lèi)型,但是總歸是有些我們自己的項(xiàng)目需要,我們需要?jiǎng)?chuàng)建自定義后綴的組件,這時(shí)候就不得不舍棄cli了,那么能不能使用自定義的方式來(lái)達(dá)到腳手架創(chuàng)建呢?
angular 腳手架創(chuàng)建的方式
我們首先來(lái)看看angular-cli提供的一些命令是怎么創(chuàng)建文件的。
看angular文檔我們可以看到這個(gè)詞:Schematic,這個(gè)詞意為原理圖。Schematic是一個(gè)腳手架庫(kù),定義如何通過(guò)創(chuàng)建、修改、重構(gòu)或移動(dòng)文件和代碼來(lái)生成或轉(zhuǎn)換編程項(xiàng)目。Angular Cli使用原理圖生成和修改項(xiàng)目文件。庫(kù)開(kāi)發(fā)人員可以創(chuàng)建原理圖,使Cli能夠生成其已發(fā)布的庫(kù)??梢圆榭?a target="_blank" rel="external nofollow" >https://www.npmjs.com/package/@angular-devkit/schematics。
那這樣的話,我們可以知道angular是借助的Schematic來(lái)生成項(xiàng)目文件。再查看發(fā)現(xiàn)node_module里面有個(gè)@Schematics/angular,里面定義了我們可以使用cli生成的所有文件,包括components\class\enum\interface等等。
點(diǎn)開(kāi)查看components,里面有一些ts文件,還有一個(gè)files文件夾,里面包含著所有我們生成component的文件:
__name@dasherize@if-flat__
- __name@dasherize__.component.__styleext__
- __name@dasherize__.component.html
- __name@dasherize__.component.spec.ts
- __name@dasherize__.component.ts
那想想,在我們運(yùn)行Cli創(chuàng)建組件的時(shí)候,會(huì)使用這里的模板,用file文件夾里面的文件生成項(xiàng)目組件。其他的先不管,我們按照這里的components是不是可以來(lái)構(gòu)造我們自己的“原理圖”呢?
自定義原理圖
先看看我們的需求,我們現(xiàn)在項(xiàng)目的項(xiàng)目里面,頁(yè)面是page,按照angular原來(lái)的寫(xiě)法,所有的page的組件都是:XXXX.component.ts。我們?yōu)榱藢㈨?yè)面和組件進(jìn)行區(qū)分,頁(yè)面的文件都是XXX.page.ts。我們先在node_module/@Schematics/angula/下面復(fù)制component新建一個(gè)page。
現(xiàn)在,將page下面的files文件夾中的文件名.component都改為.page(由于我們不用單元測(cè)試文件,直接刪除.spec.ts文件即可):
page
- files
- __name@dasherize@if-flat__
- __name@dasherize__.page.__styleext__
- __name@dasherize__.page.html
- __name@dasherize__.page.ts
- index.d.ts
- index.js 命令運(yùn)行時(shí)會(huì)執(zhí)行這個(gè)js文件
- schema.d.ts
- schema.json 定義了這個(gè)生成器命令可以接受的參數(shù)
接下來(lái)再看page里面的index.js,這個(gè)js文件在我們跑自己的命令的時(shí)候會(huì)執(zhí)行??催@個(gè)文件,里面的代碼雖然有點(diǎn)看不懂,但是猜猜還是可以的,有些關(guān)鍵地方:
const componentPath = `/${options.path}/` + (options.flat ? '' : core_1.strings.dasherize(options.name) + '/') + core_1.strings.dasherize(options.name) + '.component'; const classifiedName = core_1.strings.classify(`${options.name}Component`);
類(lèi)似于這樣的地方,我們發(fā)現(xiàn)就是創(chuàng)建對(duì)應(yīng)的組件文件和里面的組件類(lèi)。所以我們把所有.component和}Component的地方替換為.page和}Page:
const componentPath = `/${options.path}/` + (options.flat ? '' : core_1.strings.dasherize(options.name) + '/') + core_1.strings.dasherize(options.name) + '.page'; const classifiedName = core_1.strings.classify(`${options.name}Page`);
然后接下來(lái)再看page/files/__name@dasherize__.page.ts:
import { Component, OnInit<% if(!!viewEncapsulation) { %>, ViewEncapsulation<% }%><% if(changeDetection !== 'Default') { %>, ChangeDetectionStrategy<% }%> } from '@angular/core'; @Component({ selector: '<%= selector %>',<% if(inlineTemplate) { %> template: ` <p> <%= dasherize(name) %> works! </p> `,<% } else { %> templateUrl: './<%= dasherize(name) %>.component.html',<% } if(inlineStyle) { %> styles: []<% } else { %> styleUrls: ['./<%= dasherize(name) %>.component.<%= styleext %>']<% } %><% if(!!viewEncapsulation) { %>, encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection !== 'Default') { %>, changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %> }) export class <%= classify(name) %>Component implements OnInit { constructor() { } ngOnInit() { } }
這個(gè)是生成的組件的ts模板,我們需要根據(jù)我們的需求來(lái)改造,首先是文件里面的類(lèi),既然我們現(xiàn)在的文件名是XXX.page.ts,那么里面的類(lèi)也就需要時(shí)XXXPage形式的,并且我們的頁(yè)面是不允許作為指令的形式出現(xiàn)的,所以也要去掉selector元數(shù)據(jù)。那綜合下來(lái),我們的__name@dasherize__.page.ts應(yīng)該修改為:
import { Component, OnInit<% if(!!viewEncapsulation) { %>, ViewEncapsulation<% }%><% if(changeDetection !== 'Default') { %>, ChangeDetectionStrategy<% }%> } from '@angular/core'; @Component({ templateUrl: './<%= dasherize(name) %>.page.html', <% if(inlineStyle) { %> styles: []<% } else { %> styleUrls: ['./<%= dasherize(name) %>.page.<%= styleext %>']<% } %><% if(!!viewEncapsulation) { %>, encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection !== 'Default') { %>, changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %> }) export class <%= classify(name) %>Page implements OnInit { constructor() { } ngOnInit() { } }
OK,目前為止,我們的“原理圖”就創(chuàng)建的差不多了,我們現(xiàn)在需要加入cli指令上去。在@Schematics/angular/collection.json里面定義了cli的命令,同樣,先觀察componet的命令:
"component": { "aliases": [ "c" ], // 簡(jiǎn)寫(xiě)形式 "factory": "./component", // 采用生成器 "description": "Create an Angular component.", "schema": "./component/schema.json" },
我們來(lái)創(chuàng)建我們自己的命令:
"component": { "aliases": [ "pa" ], // 簡(jiǎn)寫(xiě)形式 "factory": "./page", // 采用生成器 "description": "Create an Angular component page.", "schema": "./page/schema.json" },
測(cè)試命令
目前為止,我們已經(jīng)添加好了我們自己的生成命令,現(xiàn)在來(lái)嘗試著生成一個(gè)page組件,在app/pages/user下面生成組件user-test,命令:ng g page pages/user/user-test,查看結(jié)果:
CREATE src/app/pages/user/user-test/user-test.page.css (0 bytes) CREATE src/app/pages/user/user-test/user-test.page.html (28 bytes) CREATE src/app/pages/user/user-test/user-test.page.ts (239 bytes) UPDATE src/app/pages/user/user.module.ts (1803 bytes)
看看生成的ts文件:
import { Component, OnInit } from '@angular/core'; @Component({ templateUrl: './user-test.page.html', styleUrls: ['./user-test.page.css'] }) export class UserTestPage implements OnInit { constructor() { } ngOnInit() { } }
非常好啊,完全滿足我們的需求。
慢著,我現(xiàn)在項(xiàng)目中使用的是less,而且使用component創(chuàng)建的組件里面的樣式文件都是less,為啥我們自定義的生成的是css文件???
很可能是沒(méi)有識(shí)別我們自定義的less,那我們自定義的less是怎么定的呢?看看angular.json文件中有個(gè)project里面:
"schematics": { "@schematics/angular:component": { "styleext": "less" } },
也就是說(shuō),我們?cè)谶@里配置了生成component組件時(shí),styleext為less,我們的page命令是沒(méi)有配置的,所以會(huì)找默認(rèn)的樣式文件后綴。那我們?cè)谶@里嘗試加上試試看:
"schematics": { "@schematics/angular:component": { "styleext": "less" }, "@schematics/angular:page": { "styleext": "less" } },
再生成一下:
CREATE src/app/pages/user/user-test/user-test.page.less (0 bytes) CREATE src/app/pages/user/user-test/user-test.page.html (28 bytes) CREATE src/app/pages/user/user-test/user-test.page.ts (240 bytes) UPDATE src/app/pages/user/user.module.ts (1804 bytes)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
AngularJS基于ui-route實(shí)現(xiàn)深層路由的方法【路由嵌套】
這篇文章主要介紹了AngularJS基于ui-route實(shí)現(xiàn)深層路由的方法,涉及AngularJS路由嵌套操作相關(guān)實(shí)現(xiàn)步驟與技巧,需要的朋友可以參考下2016-12-12詳解AngularJs中$sce與$sceDelegate上下文轉(zhuǎn)義服務(wù)
這篇文章給大家詳細(xì)介紹了AngularJs提供的嚴(yán)格上下文轉(zhuǎn)義服務(wù)$sce與$sceDelegate,文中介紹的很詳細(xì),有需要的朋友們可以參考借鑒。2016-09-09AngularJS實(shí)現(xiàn)分頁(yè)顯示數(shù)據(jù)庫(kù)信息
這篇文章主要為大家詳細(xì)介紹了AngularJS實(shí)現(xiàn)分頁(yè)顯示數(shù)據(jù)庫(kù)信息效果的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-07-07AngularJS中ng-options實(shí)現(xiàn)下拉列表的數(shù)據(jù)綁定方法
今天小編就為大家分享一篇AngularJS中ng-options實(shí)現(xiàn)下拉列表的數(shù)據(jù)綁定方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08AngularJS ng-repeat指令中使用track by子語(yǔ)句解決重復(fù)數(shù)據(jù)遍歷錯(cuò)誤問(wèn)題
這篇文章主要介紹了AngularJS ng-repeat指令中使用track by子語(yǔ)句解決重復(fù)數(shù)據(jù)遍歷錯(cuò)誤問(wèn)題,結(jié)合實(shí)例形式分析了ng-repeat指令遍歷JavaScript數(shù)組錯(cuò)誤的原因與相關(guān)解決技巧,需要的朋友可以參考下2017-01-01AngularJS入門(mén)教程之 XMLHttpRequest實(shí)例講解
本文主要講解 AngularJS XMLHttpRequest,這里給大家整理相關(guān)資料并提供實(shí)例代碼,有需要的小伙伴參考下2016-07-07AngularJS入門(mén)教程之REST和定制服務(wù)詳解
本文主要講解 AngularJS REST和定制服務(wù)的知識(shí),這里幫大家整理了相關(guān)知識(shí),并附示例代碼,詳細(xì)講解了RES和定制服務(wù)的知識(shí),有興趣的小伙伴可以參考下2016-08-08