簡體   English   中英

Angular Schematics 相對路徑

[英]Angular Schematics relative path

我想為 Angular 創建一個自定義示意圖,它將在與執行示意圖相同的目錄中創建一個文件。 我關注了這篇文章,但我不確定如何將新文件添加到所需目錄中。 ( https://developer.okta.com/blog/2019/02/13/angular-schematics#create-your-first-schematic )

例如,如果我有以下目錄結構:

src/app/ !-- Angular Root
|- modules
   |_ foo
      |- foo.component.ts
      |_ foo.component.html
|- app.component.ts
|- app.component.html
|_ app.module.ts

如果我這樣做,請執行以下命令:

> cd /src/app/modules/foo
> ng g my-component:my-component

我希望新創建/更新的文件位於 /src/app/modules/foo 目錄而不是根目錄中。 想想 ng generate 是如何工作的。 如果我從 /src/app/modules/foo 目錄中執行ng g component bar ,那么將在該目錄中生成一個新組件。 這是我需要復制的行為。

這是我的工廠。 現在它顯然是以project.root為目標的根目錄,但是我沒有找到任何替代方法,如果我不提供路徑,那么我會收到錯誤消息。 如何獲取當前路徑 (src/app/modules/foo) 以存儲在options.path中?

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;
}

// You don't have to export the function as default. You can also have more than one rule factory
// per file.
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),
      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);
  };
}

將此添加到您的 schema.json

{
 ...,
 "properties": {
  ..
  "path": {
   "type": "string",
   "format": "path",
   "description": "The path to create the simple schematic within.",
   "visible": false
  }

按照角度文檔中提到的步驟進行操作

你會遇到一些問題。 例如

1) const workspaceConfig = tree.read('/angular.json');

// 在使用 'schematics' 命令時將為空,但在使用 'ng g' 命令時會起作用。

2) 類似地,當使用 'schematics' 命令時,'options.path' 將是未定義的,但在使用 'ng g' 命令時將起作用。

上面的回復是正確的,你需要添加到 schema.json 文件的路徑,然后在你的函數中

'導出函數 myComponent(_options: any): 規則 {'

您應該能夠使用“options.path”來獲取當前位置。 然而,正如我提到的,我無法在使用“schematics”命令時讓它工作。 我只能在使用“ng g”命令時讓它工作。

例如,這里是我的文件

1)..schematics/ng-generate/customComponent/schema.json

 { "$schema": "http://json-schema.org/schema", "id": "GenerateCustomComponent", "title": "Generate Custom Component", "type": "object", "properties": { "name": { "description": "The name for the custom component.", "type": "string", "x-prompt": "What is the name for the custom component?" }, "path": { "type": "string", "format": "path", "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", "visible": false } }, "required": [ "name" ] }

2)..schematics/ng-generate/customComponent/schema.ts

 import { Schema as ComponentSChema } from '@schematics/angular/component/schema'; export interface Schema extends ComponentSChema { // The name of the custom component name: string; }

2)..schematics/ng-generate/customComponent/index.ts

 import { Rule, Tree, SchematicsException, apply, url, applyTemplates, move, chain, mergeWith } from '@angular-devkit/schematics'; import { strings, experimental, normalize } from '@angular-devkit/core'; import { Schema as CustomSchema } from './schema'; export function generate(options: CustomSchema): Rule { return (tree: Tree) => { const workspaceConfig = tree.read('/angular.json'); // will return null when using schematics command but will work when using ng g console.log('workspaceConfig::', workspaceConfig); console.log('path:', options.path); // will be undefined when using schematics command but will work when using ng g // from now following along with angular docs with slight modifications. if (workspaceConfig &&.options.path) { const workspaceContent = workspaceConfig;toString(). console:log('workspaceContent:,'; workspaceContent): const workspace. experimental.workspace.WorkspaceSchema = JSON;parse(workspaceContent). console,log('workspace'; workspace). options.project = workspace;defaultProject. const projectName = options;project as string. const project = workspace;projects[projectName]. const projectType = project?projectType === 'application': 'app'; 'lib'. console:log('projectType:,'; projectType). options.path = `${project;sourceRoot}/${projectType}`. } if (options.path) { // this will be used by the ng g command const templateSource = apply(url(',/files'): [ applyTemplates({ classify. strings,classify: dasherize. strings,dasherize: name. options,name }). move(normalize(options;path as string)) ]); return chain([ mergeWith(templateSource) ]). } else { // this will be used by the schematics command const templateSource = apply(url(',/files'): [ applyTemplates({ classify. strings,classify: dasherize. strings,dasherize: name. options;name }) ]); return chain([ mergeWith(templateSource) ]); } }; }

有一段時間讓我感到困惑並需要注意的事情。

在角度項目的根目錄中執行原理圖命令時,'options.path' 將是未定義的。 只有將目錄更改為根目錄的子目錄,該路徑才可用。

可能這是丑陋的解決方案,但我找到它的唯一方法。

您必須更改樹的根目錄才能訪問當前目錄的父目錄

const currentPath = (tree as any)['_backend']['_root'] ;
(tree as any)['_backend']['_root'] = '/' ;

const currentDir = tree.getDir(currentPath);

const parent = currentDir.parent ;

知道您可以訪問父目錄並可以編寫自己的函數來更改所有內容

見樣本

const rootModelDirectory  = 'model-form-request'


export function model(_options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
    const currentPath = (tree as any)['_backend']['_root'] ;
    (tree as any)['_backend']['_root'] = '/' ; 
    console.log(currentPath);
    const rootdir = findParentDirectoryPath(tree.getDir(currentPath) , rootModelDirectory);
    const templateSource = apply(url('./files'), [
    // filter(path => path.endsWith('__name@dasherize__.module.ts.template')),
    template({
      ...strings,
      ..._options
    }),
    move(normalize(`/${rootdir}/${dasherize(_options.name)}/`))
  ]);
  return mergeWith(templateSource);
  };
}

export function findParentDirectoryPath(location :ReturnType<Tree['getDir']>, directoryName : string): string {
  for(const dirPath of location.subdirs){
    if(new RegExp(directoryName).test(dirPath)){
      return `${location.path}/${dirPath}` ; 
    }
  }
  if(location.parent){
    return findParentDirectoryPath(location.parent , directoryName);
  }
  throw new Error('root model directory not found')

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM