3
votes

Schémas angulaires: comment définir les variables par défaut dans schema.json? (nom du projet)

Comment définir des variables par défaut pour les "propriétés" des schémas angulaires dans schema.json?

J'ai essayé de regarder dans code source angulaire lui-même mais je ne pouvais pas le comprendre. J'ai découvert que si le mot-clé "$ source" est utilisé, la chaîne devant lui sera résolue en une certaine valeur.

Par exemple, "argv" et "projectName" sont deux variables qui ils seront résolus en valeurs réelles lorsqu'ils seront écrits comme ceci:

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

ou

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

Alors, comment puis-je définir ma propre variable? Sont-ils réellement des variables? Quelles autres variables sont disponibles?

J'ai également trouvé un autre exemple qui ne fonctionne pas si je le copie-collez dans mon propre projet:

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

Retrouvez ici le code complet

D'après mon observation, je m'attends à ce que cela soit résolu en une valeur, mais je deviens undefiend.

Merci d'avance!


2 commentaires

Ce n'est pas une réponse, seulement un commentaire: le meilleur article sur les schémas qui fonctionnent (Angular 7) que j'ai trouvé est medium.com/rocket-fuel/...


Ce n'est pas une bonne référence pour cette question. La chose la plus proche que j'ai trouvée est cet article de Hakernoon , ce qui n'est toujours pas la réponse à ma question.


5 Réponses :


1
votes

Les variables que vous définissez dépendront certainement du comportement de votre schéma. Par exemple, j'ai un nouveau schéma d'application avec une variable personnalisée pour permettre aux utilisateurs de spécifier le type d'authentification à échafauder dans l'application:

Pour appeler ce schéma à partir de la ligne de commande, l'utilisateur doit saisir ng new my-application-schematic- with-sso --collection = @ simple-schematic --authentication = SSO (le x-prompt fournit une liste d'options à l'utilisateur si le commutateur de ligne de commande n'est pas explicitement fourni. Voir aussi Schéma angulaire ng-new pour les options de style .

{
  "$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"
    }
  }
}

Ce schéma utilise également le modèle argv pour capturer le nom du espace de travail:

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

La syntaxe de la ligne de commande pour appeler ce schéma ressemblerait à quelque chose comme ng new my-new-schematic --collection = @ simple-schematic et générerait un nouvel espace de travail intitulé my-new-schematic . Étant donné que l'indicateur --authentication n'est pas fourni, l'utilisateur sera invité à sélectionner Aucun ou SSO

Un comportement important lié au schéma et aux variables que vous définissez qui peut conduire au problème indéfini (en particulier lorsque votre variable a une valeur par défaut) que vous avez noté dans votre question d'origine n'est pas de lier correctement le schéma au commande schématique.

Par exemple, la propriété schema de l'objet schématique ng-new , indique comment traduire les entrées CLI fournies en objet correspondant transmis à votre schéma personnalisé.

"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"
            }
        ]
    }
},

Deux captures d'écran différentes du débogage des tests selon que la propriété schema est spécifiée ou non:

 Aucune propriété de schéma ne parvient à récupérer les valeurs par défaut spécifiées

Et encore une fois avec le schéma explicitement spécifié: La propriété du schéma reprend les valeurs par défaut


4 commentaires

Veuillez relire ma question! Cela n'a aucun rapport avec ma question! Je demande classer les valeurs par défaut dynamiquement par le framework , et non "Comment donner des options aux utilisateurs".


J'adorerais jeter un autre coup d'œil. J'ai interprété " Comment puis-je définir ma propre variable? S'agit-il réellement de variables? Quelles autres variables sont disponibles? " comme votre question. Pouvez-vous reformuler le problème que vous essayez de résoudre, c'est-à-dire: "Je voudrais ajouter une valeur par défaut à une propriété dans un schéma personnalisé?" (Je pense que je peux vous aider et je modifierai ma réponse une fois que j'aurai ce petit détail supplémentaire de votre part).


Bien sûr, c'est génial! J'ai besoin que la CLI angulaire remplisse la valeur par défaut des paramètres de la commande de schémas en cours d'exécution. Par exemple, le mot-clé «argv» est quelque chose que la CLI comprend et le remplace (ou transmet) la bonne valeur au moment de l'exécution. Ou un autre exemple, comme je l'ai décrit dans la question, est le {"$ source": "projectName"} qui serait remplacé par le nom réel du projet. Ce dont j'ai besoin, c'est de pouvoir dire à Angular de transmettre une valeur à la commande par elle-même à l'utilisateur qui ne sera pas obligé de l'écrire à chaque fois.


Par exemple, disons que je veux obtenir la version angular-core installée et la transmettre aux schémas via un paramètre.



0
votes

Utilisez simplement "default": "YOUR_VALUE" mais n'oubliez pas d'exécuter npm run build après.


1 commentaires

C'est le cas d'utilisation de base, la question est de savoir comment le rendre dynamique, et non "comment fournir une valeur par défaut?". Comment rendre "YOUR_VALUE" pragmatiquement modifiable?



0
votes

OffTopic: il y a aussi une interpolation .
Vous pouvez le trouver dans packages / _ / devkit / package / schema.json . ;-)


Vous pouvez jeter un œil dans
packages / angular_devkit / core / src / json / schema / registry.ts
où vous pouvez trouver une méthode appelée
addSmartDefaultProvider (source: string, provider: SmartDefaultProvider )

Il semble qu'ils utilisent cette méthode pour créer des "valeurs par défaut intelligentes" comme ils l'appellent, mais pas toujours.
La vérification de argv dans packages / angular / cli / utilities / json-schema.ts se fait via
const $ defaultIndex = (json.isJsonObject ($ default) && $ default ['$ source'] == 'argv')
Donc pas d'approche unifiée. Tout à fait hacky à mon humble avis.

Dans le corps de la méthode addSmartDefaultProvider , vous trouverez le bloc amusant suivant:

// 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,
);

Si vous allez plus loin, vous découvrirez:


0 commentaires

0
votes

DevRok était presque là. Je pense que pour répondre pleinement à votre question, nous devons examiner l'utilisation de addSmartDefaultProvider . J'ai trouvé ces références dans la branche 7.3.x (car c'est ce que nous utilisons encore au travail).

Référence 1 dans packages / angular / cli / models / schematic-command.ts

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


0 commentaires

0
votes

Je ne sais pas comment vous le définissez dans schema.json ... Je ne sais pas s'il existe une paire clé / valeur pour celui-ci ("default": "value" n'a rien fait).

J'ai donc travaillé autour avec une instruction if dans la fonction factory (index.ts)

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

Fonctionne assez bien.


0 commentaires