2013-12-21 8 views
30

私は最初のYeomanジェネレータを作成しています。これはユーザーにさまざまな入力を促し、応答に基づいてファイルを条件付きで作成します。私は、ユーザー入力に基づいてサブルーチン(Yeomanサブジェネレーターかもしれません)を呼び出すことができ、それに引数を渡すことができる必要があります。Yeoman:ユーザー提供の引数を使用してサブジェネレータを呼び出す

名前付き関数(自動的には実行されない)を使用したい理由は、ユーザーの応答で複数の関数を組み合わせて呼び出す必要があり、関数が単独で実行されることがあります。私が試してみました何

を私は、ユーザーがそれらを要求した場合にのみ、ファイルのセットを作成していますので、サブ発電機は、移動するための方法だった考え出しました。しかし、を条件付きでと呼んで問題を解決し、ユーザーからの入力を渡しています。私はhookForを使ってみましたが、アサーションエラーが発生しました:hookFor must be used within the constructor only。 (私はそれがデフォルトで実行されることを望んでいないので、私はthis.prompt(prompts, function (props)からサブジェネレータを呼び出しています)。

質問:

どのように私は、ユーザーが(プロンプト経由で)それを要求した場合にのみ、ルーチンを呼び出し、そのルーチンにいくつかのユーザーが提供する情報を渡すのですか?

あなたが十分親切であれば、私が何か明白なものを試したと仮定しないでください。

答えて

32

のは、次の2つのサブ・ジェネレータ(ブログ・サーバーおよびブログ・クライアント)と発電機generator-blog(BlogGenerator)持って考えてみましょう:あなたはyo blogを実行するときですから、いくつかのオプションをユーザーに何をお願いする

app\index.js 
client\index.js 
server\index.js 

をし、 (オプションで)サブジェネレータを実行します。

サブジェネレータを実行するには、this.invoke("generator_namespace", {options: {}})を呼び出す必要があります。 私たちが渡した2番目の引数は、optionsフィールドを持つことができます - それはジェネレータに渡されるオプションオブジェクトです。アプリの\のindex.jsで

:クライアントの\ index.jsで

BlogGenerator.prototype.askFor = function askFor() { 
    var cb = this.async(); 

    // have Yeoman greet the user. 
    console.log(this.yeoman); 

    var prompts = [{ 
    name: 'appName', 
    message: 'Enter your app name', 
    default: 'MyBlog' 
    }, { 
    type: 'confirm', 
    name: 'createServer', 
    message: 'Would you like to create server project?', 
    default: true 
    }, { 
    type: 'confirm', 
    name: 'createClient', 
    message: 'Whould you like to create client project?', 
    default: true 
    }]; 

    this.prompt(prompts, function (props) { 
    this.appName = props.appName; 
    this.createServer = props.createServer; 
    this.createClient = props.createClient; 

    cb(); 
    }.bind(this)); 
} 

BlogGenerator.prototype.main = function app() { 
    if (this.createClient) { 
    // Here: we'are calling the nested generator (via 'invoke' with options) 
    this.invoke("blog:client", {options: {nested: true, appName: this.appName}}); 
    } 
    if (this.createServer) { 
    this.invoke("blog:server", {options: {nested: true, appName: this.appName}}); 
    } 
}; 

var BlogGenerator = module.exports = function BlogGenerator(args, options, config) { 
    var that = this; 
    yeoman.Base.apply(this, arguments); 
    // in this.options we have the object passed to 'invoke' in app/index.js: 
    this.appName = that.options.appName; 
    this.nested = that.options.nested; 
}; 

BlogGenerator .prototype.askFor = function askFor() { 
    var cb = this.async(); 

    if (!this.options.nested) { 
    console.log(this.yeoman); 
    } 
} 

UPDATE 2015年12月21日
廃止とすべきであるinvokeを使用してcomposeWithに置き換えてください。しかし、それは可能な限り簡単ではありません。 invokecomposeWithの主な違いは、サブジェネレータを制御する能力がないことです。あなたはそれらを使って宣言することしかできませんでした。また、私はyeoman.Baseyeoman.generators.Baseを置き換え削除

BlogGenerator.prototype.main = function app() { 
    if (this.createClient) { 
    this.composeWith("blog:client", { 
     options: { 
      nested: true, 
      appName: this.appName 
     } 
     }, { 
     local: require.resolve("./../client") 
     }); 
    } 
    if (this.createServer) { 
    this.composeWith("blog:server", { 
     options: { 
      nested: true, 
      appName: this.appName 
     } 
     }, { 
     local: require.resolve("./../server") 
     }); 
    } 
}; 

:ここ
は、上記からmain方法は次のようになります方法です。

+0

**正確には**私が探していたものです。ありがとう。 – Fiona

+0

私はこれが古いことを知っていますが、私が探しているものに近いです。私の問題は、私のサブジェネレータが "yeoman.generators.NamedBase"を拡張していることです。このコードを実行すると、「エラー:必須の引数名を指定しませんでした!」というメッセージが表示されます。 .invoke()によって呼び出されるサブジェネレータにも名前を渡す(つまり、 "yo make:controller test"では "test")方法を理解しようとしています。どんな助け? – ItJustWerks

+1

これを得ました:this.invoke( "make:controller"、{options:{入れ子:真、...}、args:[this.name]});このエラーが発生した場合は、 – ItJustWerks

2

あなたが一緒に発電機を構成するときに発電機を分離し、実行コンテキストループがお手伝いします「メイン・ジェネレータ」を使用している場合促し、すべての可能な実行シナリオ、条件のチェックをカバーすることができます。複合発電機に構成を渡す場合はoptions.composeWith('my-genertor', { 'options' : options })としてください。

.composeWithを使用している場合、すべてのジェネレータ、次に優先度グループに対して優先グループ機能(例:promptingwriting ...)が実行されます。あなたは.composeWith generatorBgeneratorAの内側から呼び出した場合、実行は例えば、次のようになります。あなたが別の発電機間の実行を制御したい場合は

generatorA.prompting => generatorB.prompting => generatorA.writing => generatorB.writing

が、私はあなたが「メイン」ジェネレータを作成することをお勧めしていますhttp://yeoman.io/authoring/composability.html#orderのように一緒に構成します。

// In my-generator/generators/turbo/index.js 
module.exports = require('yeoman-generator').Base.extend({ 
    'prompting' : function() { 
    console.log('prompting - turbo'); 
    }, 

    'writing' : function() { 
    console.log('prompting - turbo'); 
    } 
}); 

// In my-generator/generators/electric/index.js 
module.exports = require('yeoman-generator').Base.extend({ 
    'prompting' : function() { 
    console.log('prompting - zap'); 
    }, 

    'writing' : function() { 
    console.log('writing - zap'); 
    } 
}); 

// In my-generator/generators/app/index.js 
module.exports = require('yeoman-generator').Base.extend({ 
    'initializing' : function() { 
    this.composeWith('my-generator:turbo'); 
    this.composeWith('my-generator:electric'); 
    } 
}); 
関連する問題