4

如何在 schema.json 中定义角度示意图“属性”的默认变量?

我试图研究角度源代码本身,但我无法弄清楚。我发现如果使用关键字“$source”,它前面的字符串会以某种方式解析为某个值。

例如,“argv”和“projectName”是两个变量,当他们这样写时,它们将被解析为实际值:

     "project": {
         "alias": "p",
         "type": "string",
         "description": "The name of the project.",
         "$default": {
             "$source": "projectName"
         }
     },

或者

    "name": {
      "type": "string",
      "description": "The package name for the new schematic.",
      "$default": {
        "$source": "argv",
        "index": 0
      }
    },

那么如何定义自己的变量呢?它们实际上是变量吗?还有哪些可用的变量?

如果我将其复制粘贴到我自己的项目中,我还发现了另一个不起作用的示例:

    "version": {
      "type": "string",
      "description": "The version of the Angular CLI to use.",
      "visible": false,
      "$default": {
        "$source": "ng-cli-version"
      }
    },

在这里找到完整的代码

根据我的观察,我希望这可以解决一个值,但我不相信。

提前谢谢各位!

4

5 回答 5

1

您定义的变量肯定取决于原理图的行为。例如,我有一个带有自定义变量的新应用程序示意图,以允许用户指定要在应用程序中搭建的身份验证类型:

要从命令行调用此示意图,用户将输入ng new my-application-schematic-with-sso --collection=@simple-schematic --authentication=SSOx-prompt如果未显式提供命令行开关,则向用户提供选项列表。另请参见Angular ng-new schema for style options

"authentication": {
    "description": "The authentication strategy to use",
    "default": "None",
    "x-prompt": {
        "message": "Which authentication strategy would you like to use?",
        "type": "list",
        "items": [
            {
                "value": "None",
                "label": "None"
            },
            {
                "value": "SSO",
                "label": "SSO"
            }
        ]
    }
},

此原理图还利用该argv模式来捕获工作区的名称:

"name": {
    "description": "The name of the workspace",
    "type": "string",
    "$default": {
        "$source": "argv",
        "index": 0
    }
},...

所以调用这个原理图的命令行语法看起来像这样ng new my-new-schematic --collection=@simple-schematic,并且会生成一个名为my-new-schematic的新工作区。由于--authentication未提供该标志,因此将提示用户选择NoneSSO

与您定义的架构和变量相关的一项重要行为可能导致您在原始问题中指出的未定义问题(尤其是当您的变量具有默认值时),即未将架构正确链接到原理图命令。

例如,原理图对象的schema属性ng-new指示如何将提供的 CLI 输入转换为传递给自定义原理图的相应对象。

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "extends": "@schematics/angular",
  "schematics": {
    "ng-new": {
      "description": "new workspace",
      "factory": "./ng-new",
      "schema": "./ng-new/schema.json"
    }
  }
}

根据是否schema指定属性,调试测试的两个不同屏幕截图:

没有架构属性无法获取指定的默认值

再次明确指定架构: Schema 属性采用默认值

于 2019-02-15T20:12:27.473 回答
0

DevRok 几乎就在那里。我认为要完全回答您的问题,我们需要查看addSmartDefaultProvider. 我在 7.3.x 分支中找到了这些引用(因为这是我们仍在工作中使用的)。

packages/angular/cli/models/schematic-command.ts 中的参考 1

workflow.registry.addSmartDefaultProvider('projectName', () => {

packages/angular/cli/commands/new-impl.ts 中的参考 2

this._workflow.registry.addSmartDefaultProvider('ng-cli-version', () => version);

所以它似乎ng-cli-version只在运行时起作用ng new,而不是ng generate。目前看来,ng-cli-version并且projectName是唯一定义的智能默认提供程序,但将来添加更多内容应该是相当直接的。

为了完整起见,我想参考DevRok对在packages/angular/cli/utilities/json-schema.tsargv中定义的伪智能默认提供程序的回答。

于 2020-01-15T16:13:48.260 回答
0

题外话:还有interpolation
你可以在packages/_/devkit/package/schema.json. ;-)


您可以查看在
packages/angular_devkit/core/src/json/schema/registry.ts
哪里可以找到名为的方法
addSmartDefaultProvider<T>(source: string, provider: SmartDefaultProvider<T>)

看起来他们正在使用这种方法来创建他们如何称呼它的“智能默认值”,但并非总是如此。
argvpackages/angular/cli/utilities/json-schema.ts是通过
const $defaultIndex = (json.isJsonObject($default) && $default['$source'] == 'argv')
所以没有统一的方法完成的。相当hacky恕我直言。

addSmartDefaultProvider方法主体中,您会发现以下有趣的块:

// We cheat, heavily.
compilationSchemInfo.smartDefaultRecord.set(
// tslint:disable-next-line:no-any
   JSON.stringify((it as any).dataPathArr.slice(1, (it as any).dataLevel + 1) as string[]),
   schema,
);

如果你要更进一步,你会发现:

于 2019-12-17T12:48:03.710 回答
0

只需使用"default": "YOUR_VALUE"但不要忘记运行npm run build

于 2019-06-24T12:59:55.653 回答
0

不确定您如何在 schema.json 中设置它...不确定是否有一个键值对(“default”:“value”没有做任何事情)。

所以我在工厂函数(index.ts)中使用了一个 if 语句

if (!_options.yourVariable) {
     _options.yourVariable = 'yourDefaultValue'
}

工作得很好。

于 2020-05-10T18:28:24.863 回答