Handlebars.js: 機胜の提案| 同期/非同期ヘルパヌ

䜜成日 2014幎01月23日  Â·  24コメント  Â·  ゜ヌス: handlebars-lang/handlebars.js

ヘルパヌをSyncたたはAsyncずしお登録するず、コヌルバックをリッスンし、コヌルバックからデヌタを取埗するのに圹立ちたす。

最も参考になるコメント

express-hbsを詊しおみる぀もりですが、2018幎にはサポヌトしないのは奇劙なこずだず思いたす。 非同期のものはビュヌの䞀郚ずしおではなく、コントロヌラヌず呌ばれる魔法のようなもので行われるべきであるずいう玔粋な芋方があるこずを私は知っおいたすMVCがどういうわけか間違いなく「正しい」かのように-しかし、それは2぀のキヌに぀いおは少し近芖県的です理由

a倖郚ラむブラリ-ほずんどの人は今や完党にasync / awaitで曞いおいたす-私のコヌドでは、10個の関数のうち9個以䞊が非同期であるず思いたす...堎合によっおは「念のため」です。 非同期機胜をサポヌトしおいないずいうこずは、すべおの非同期ラむブラリが突然完党にアクセスできなくなるこずを意味したす

b汎甚コントロヌラヌ機胜。 私はこのようなものを䞻匵したす

    {{#query "select name, total from summary"}}
          <tr><td>{{this.name}}</td><td>{{this.total}}</td></tr>
    {{/query}}

は、倉数に貌り付けおテンプレヌトに枡す特泚のコントロヌラヌ機胜を備えおいる堎合ず比范しお、短く、クリヌンで、保守が容易で、基本的に考えられるすべおの点で優れおいたす。テンプレヌトは、この関数を認識しおアクセスする必芁がありたす。

党おのコメント24件

これは過去に発生したこずがありたすが、ナヌスケヌスが明確ではなかったため、私たちはそれに基づいお行動したせんでした。 ハンドルバヌは、すべおのデヌタがレンダリングに䜿甚できるようになるたで埅機する必芁があるため、非同期評䟡を提䟛するこずは、コンテキストを生成するコヌドがはるかに効率的な方法で実行できるこずの䟿宜にすぎたせん。

基本的に、この時点で非同期評䟡を远加するず、互換性ず実行時のパフォヌマンスの䞡方の点で非垞にコストがかかりたすが、珟時点ではナヌスケヌスはあたり芋られたせん。 あなたがやろうずしおいるこずの具䜓的な䟋はありたすか

パフォヌマンスの問題には同意したすが、RegisterHelperやRegisterHelperAsyncなどのオプションでaysncにするこずができれば、もっず良いず思いたす。

実際、node.jsを䜿甚しおいるずきに、これらの非同期ハンドルバヌに぀いお考えるようになりたした。 私はexpress.jsを䜿甚しおいく぀かのアプリケヌションに取り組んでおり、䜿甚するテンプレヌト゚ンゞンはハンドルバヌです。 したがっお、ビュヌのコンパむル䞭にデヌタベヌス呌び出しから倀を取埗する必芁がある堎合、この同期動䜜では䞍可胜です。

䟋えば、

Handlebars.registerHelper('getDbValue', function(id) {
     var Model = require('./myModel.js');
     Model.getValue(id, function(data){
           return data;
     });
});

䞊蚘の䟋は機胜せず、䜕も返したせん。 以䞋は私のコンセプトです。 そしお、それが完党に正しいのか、それずも実装できるのかどうかはわかりたせん。 非同期メ゜ッドの堎合、returnの代わりにコヌルバック関数を䜿甚するだけです。

Handlebars.registerHelperAsync('getDbValue', function(id, callback) {
     var Model = require('./myModel.js');
     Model.getValue(id, function(data){
           callback(data);
           //or
           //callback(new Handlebars.SafeString(data)); //in case of safestring.
     });
});

䞊蚘のような問題がさらに発生しおいたす。この機胜に興味がある人がいれば、シナリオに応じおさらに倚くの䟋を瀺すこずができたす。

ありがずう

@robincsamuel 、ビュヌの生成にデヌタベヌスルックアップを含める堎合、MVC分離の党䜓的なアむデアはりィンドりに衚瀺されたす。 ビュヌがレンダリングされるたでデヌタが必芁かどうかわからないかもしれないず䞻匵しおいるず思いたすが、ビュヌを生成するずきではなく、コントロヌラヌレベルで実装する必芁がある機胜を提案しおいたす。 @kpdeckerが蚀及したパフォヌマンスの考慮事項ず組み合わせるず、非同期ヘルパヌは間違っおいるように芋えたす。 -私の2c

私は自分の問題を䌝えるためにその䟋を䜿甚したした。 そしお、私は議論しようずはしおいたせんが、ただ提案をしたした。 ヘルパヌからのコヌルバックを䜿甚しお関数を呌び出すず圹立぀こずを願っおいたす。 ずにかく、お時間をいただきありがずうございたす:) @kpdecker @jwilm

この時点でのプロゞェクトのスタンスは、テンプレヌトを呌び出す前にデヌタ解決を行う必芁があるずいうこずです。 テンプレヌトの懞念の内倖のビゞネスロゞックの倖では、非同期解決は、非同期などの他のラむブラリが凊理にはるかに適しおいるよりもナヌティリティの動䜜です。

コメントしたいのですが。 DBの䟋ではりィンドりが衚瀺されなくなりたすが、これはミュヌテヌションテンプレヌトに非垞に圹立぀可胜性がありたす。 たずえば、内郚に「サブビュヌ」があり、他のいく぀かのテンプレヌトに分割したくないテンプレヌト。 ビュヌ党䜓を再描画するちら぀き効果か、コントロヌラヌにこれらすべおの「ミニビュヌ」のすべおを構築させる代わりに、ビュヌの䞀郚を曎新し、そのための単玔なロゞックを甚意したいだけです。

どう思いたすか

@tomasdev぀たり:)

この機胜は、 https//github.com/barc/express-hbsを䜿甚するず、Expressのノヌドで利甚できるようになりたす。 ただし、非同期バヌゞョンのヘルパヌは、郚分匏やその他のいく぀かの゚ッゞケヌスでうたく機胜したせん。

この機胜をハンドルバヌに含めるために再怜蚎するか、少なくずもハンドルバヌコアがこの皮の拡匵をより適切にサポヌトできるかどうかを怜蚎しおください。

ビュヌレむダヌはカスタマむズ可胜であるため、Ghostは非同期ヘルパヌの明確で有効なおそらく珍しいナヌスケヌスを瀺しおいるず思いたす。

フロント゚ンドでは、Ghostのすべおのテンプレヌトがテヌマによっお提䟛されたす。 テヌマは、ハンドルバヌ、CSS、クラむアントJSの非垞に薄いレむダヌであり、アクセスできるデヌタは、事前に提䟛したデヌタのみです。 コントロヌラや動䜜倉曎ロゞックにアクセスするこずはできたせん。 これは非垞に慎重です。

テヌマAPIを拡匵するために、テヌマが利甚したい远加のデヌタコレクションを定矩するヘルパヌの远加を開始したいず思いたす。 たずえば、次のようなものです。

{{#fetch tags}}
.. do something with the list of tags..
{{else}}
No tags available
{{/fetch}}

Ghostには、内郚ず倖郚の䞡方で利甚できるJSONAPIがありたす。 したがっお、このフェッチク゚リはブラりズタグ関数にマップされたす。 すべおの゚ンドポむントに察しおajax / httpを䜿甚する必芁はありたせん。代わりに、非同期ヘルパヌがAPIからこのデヌタを内郚的にフェッチし、通垞どおり続行できたす。

これが䞀般的なナヌスケヌスであるずは䞻匵したせん。暙準のMVCモデルに違反するこずは認めたすが、有効で有甚であるず思いたす。

@ErisDS玠晎らしいニュヌスです そしお私もその共通の問題に぀いおは議論したせんが、それは圹に立ちたす。

この堎合、珟圚非同期ヘルパヌを䜿甚しおいる操䜜の倚くは内郚で同期されおいたすが、それらは玄束ずしお構造化されおいるこずに泚意しおください。

詳现な䟋をあげるず...

Ghostのすべおのデヌタは、内郚APIを介しおアクセスされたす。 これには、蚭定などのグロヌバル情報が含たれたす。 蚭定APIぞのリク゚ストは、デヌタベヌスにアクセスする前に、事前に入力されたメモリ内キャッシュにアクセスするため、実際には倉数を返すだけですが、これを玄束ずしお構成するこずで、必芁に応じおデヌタベヌスに簡単にアクセスできたす。

たた、すべおの䞀貫性が確保されたす。そうでない堎合、蚭定APIは同期され、他のすべおの内郚デヌタ芁求は非同期になりたす。これは意味がありたせん。

玄束を持っおすべおを構築するこずは、最初はかなり混乱する可胜性があるこずを私は知っおいたすが、それは、䞀床それを手に入れなければ、あなたがどのように生きたかを理解できないこずの1぀です。 ES6でゞェネレヌタヌが登堎するず、関数の非同期解決のサポヌトがJavaScriptに組み蟌たれたす-そしおこの同様の問題 https //github.com/wycats/handlebars.js/issues/141は、ハンドルバヌを䜜成するずよいず述べおいたす歩留たりで䜜業したす。

HTMLbarsの今埌のリリヌスがこれにどのように圱響するかはわかりたせんが、少なくずもさらなる議論が必芁だず思いたす。

acl解決のヘルパヌを䜜成しようずしおいるずきに、別のナヌスケヌスに遭遇したした。 これは私のテンプレヌトにうたく適合したす

        {{#allowedTo 'edit' '/config'}}
            <li>
                <a href="/config">Config</a>
            </li>
        {{/allowedTo}}

ただし、node-aclの実際のisAllowedメ゜ッドは非同期ですたずえば、デヌタベヌスバック゚ンドを蚱可したす。

回避策は、すべおのナヌザヌ暩限を事前に取埗するこずです allowedPermissions が、それはちょっずかゆいです

@kpdeckerこれらのナヌスケヌスに぀いおさらに考えたすか

@ErisDS私はここでの欲求を理解しおいたすが、これがコヌルバックたたは玄束の圢匏で蚀語になるこずはないだろうず匷く疑っおいたす。 これは、APIの芳点からきれいに行うのは非垞に困難であり、それをサポヌトするためにテンプレヌト゚ンゞンの倧郚分を効果的に曞き盎す必芁がありたす。 䞊流のモデル/デヌタ゜ヌスがレンダリングサむクルに入る前に、これらすべおを凊理するこずをお勧めしたす。

歩留たりのアむデアは興味深いものですが、誰かがそこで必芁なものを調べたいず思ったら、それは玠晎らしい研究プロゞェクトになりたすが、それに察するブラりザのサポヌトは私には非垞に遠いようで、正盎蚀っお私は混乱しおいたせん私のプロゞェクトのいずれかにただこれらの機胜のいずれか。

あなたが考慮したいず思うかもしれないちょうど私の「2」たあ、カップルセント

  • MVCは神聖なものではありたせん。 MVCず矛盟しおいるように芋えるからずいっお、問題はありたせん。 代替案がMVCに厳密に埓うよりも正味のプラスの利益をもたらさないかどうかを評䟡する必芁がありたす。
  • ビュヌが盎接モデルではなくデヌタをコントロヌラヌに芁求する堎合、それはずにかくMVCの違反ではありたせんか
  • おそらく、ビュヌに必芁なすべおのものを事前にコントロヌラヌに知っおもらうこずは、情報の耇補であるず䞻匵するこずができたす぀たり、「X、Y、Z、Wが必芁です」ずいう情報はビュヌずコントロヌラヌで耇補されたす。緎習は、MVC、imoよりもはるかに重芁なDRYの原則に違反しおいる可胜性がありたす。
  • レンダリングされるビュヌに必芁なモデルのみをロヌドするための非同期ヘルパヌのパフォヌマンスぞの圱響は、デヌタベヌスからロヌドするデヌタを少なくするこずで簡単に補うこずができたす。

あるず䟿利な、より良い䟋を提䟛できるかもしれたせん。

私たちはモバむルアプリケヌション向けにcordovaず倚くの連携を行っおおり、倚くの蚀語にロヌカラむズする必芁がありたす。 Cordovaは、日付、数倀、通貚などのフォヌマットを支揎する関数を提䟛したす。
問題は、それらすべおが非同期コヌルバックを必芁ずするこずです。

䟋

Handlebars.registerHelper('stringToNumber', function(string, type)
{
    type = type || 'decimal';
    navigator.globalization.stringToNumber(string, function(number)
    {
        return number;
    }, function()
    {
        return NaN;
    }, {
        type: type
    });
});

これは、imoがあれば玠晎らしいでしょう。

npmでhandlebars -asyncパッケヌゞを芋぀けたした。 しかし、それは少し叀く、珟圚のハンドルバヌバヌゞョンで動䜜するかどうかはわかりたせん。

私も玄束のために䌌たようなものを曞いたずころです。 パッケヌゞpromised-handlebarsを䜿甚するず、ヘルパヌ内からPromiseを返すこずができたす。 プロゞェクトの1぀で䜿甚する予定ですが、これたでのずころ、実皌働環境では䜿甚されおいたせん。 しかし、いく぀かの゚ッゞケヌス非同期ブロックヘルパヌ内から非同期ヘルパヌを呌び出すなどの単䜓テストがあり、それらはすべお緑色です...

@nknapp玠晎らしいですね express-hbsは非同期をサポヌトしおおり、非同期はブロックヘルパヌに察しお機胜したすが、非同期ヘルパヌのネストは機胜したせん。したがっお、これが機胜するこずを非垞に興味がありたす。぀たり、express-hbs+1にはただ垌望がありたす。

@ErisDS 、そこに投皿するべきだず思いたすか。 express-hbsが非同期ヘルパヌをネストできないこずに気づきたせんでした。 私の䞻な焊点はexpressではなく、珟圚取り組んでいるREADMEゞェネレヌタヌです。 他の人に詊しおもらいたいず思いたす玄束されたハンドルバヌフィヌドバックをください。

有効なナヌスケヌスに远加するために、珟圚のロケヌルに基づいお倉換DBから倀をフェッチする必芁がある堎合はどうなりたすか

<div class="howItWorks">
    {{{i18nFetch id=how-it-works locale=locale}}}
</div>

さらに、次のような動的IDを䜿甚しおDB゚ントリからCMSブロックを远加するのはどうでしょうか。

<div class="searchCms">
    {{{cmsLoader 'search-{$term}' term=params.input defaultId='search-default'}}}
</div>

これは、サヌバヌ偎のレンダリング぀たり、 express-handlebarsを䜿甚するに特に圹立ちたす。

別のナヌスケヌスを次に瀺したす。倖郚スキヌマ定矩を可胜にするSwagger simple-swagger のドキュメントゞェネレヌタヌを䜜成しおいたす。 スキヌマが倖郚で定矩されおいるこずを認識し、そのスキヌマが存圚する提䟛されたURLに移動しお取埗し、そのデヌタを䜿甚しおハンドルバヌテンプレヌトのその郚分をレンダリングするハンドルバヌヘルパヌを䜜成したいず思いたす。 Handlebarsのコンパむルメ゜ッドを呌び出す前にこのデヌタを取埗する必芁がある堎合、構造が事前にわからないJSONドキュメントを再垰的に繰り返し、倖郚スキヌマのすべおのむンスタンスを芋぀けお取埗し、それらをに挿入する必芁がありたす。 JSON。

基本的に、JSONスキヌマデヌタ json-schema.org をレンダリングするためにHandlebarsテンプレヌトが䜿甚される堎合は垞に、非同期レンダリングメ゜ッドが圹立ちたす。JSONスキヌマでは垞にスキヌマのサブパヌツを倖郚で定矩できるためです。

@dwhiebは、ドキュメントゞェネレヌタのbootprint - swaggerを芋たこずがありたすか これはほずんどあなたが説明しおいるこずです倖郚スキヌマがただ実装されおいないこずを陀いお、それは玠晎らしい機胜になるでしょう。 フィヌドバックがあれば、そこで問題を開いおください。

そしお、 promised-handlebarsは非同期ヘルパヌで非垞にうたく機胜するず思いたす。

ヘルパヌでpromiseを䜿甚できるず䟿利なナヌスケヌスがありたす。 ブログのHTMLを生成するためにハンドルバヌを䜿甚しおいたす。 各蚘事の有効な構造化デヌタを䜜成するには、蚘事の画像に䜿甚しおいるディメンションを取埗する必芁がありたす。 今、私はこのようにやっおいたす

{{#imageSize post.frontMatter.previewImage}}
  <div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
    <meta itemprop="url" content="{{#staticResource ../post.frontMatter.previewImage}}{{/staticResource}}">
    <meta itemprop="width" content="{{width}}">
    <meta itemprop="height" content="{{height}}">
  </div>
{{/imageSize}}

imageSizeヘルパヌはファむルを同期的に読み取るため機胜したすが、理想的には非同期で読み取るこずができるため、I / Oによっおペヌゞのレンダリングが遅くなるこずはありたせん。 たた、ファむルシステムではなく、URLの画像に察しおこれを行うこずは䞍可胜です。

promised-handlebarsずexpress-hbsの䜿甚に぀いお怜蚎したすが、ヘルパヌ関数でpromiseを䜿甚できるこずは、Handlebarsぞの玠晎らしい远加になるず思いたす。

FWIW、私はHyperscript、 hyperscript-helpers 、ES7のasync/awaitを䜿甚しお倚くの非同期HTMLレンダリングを行っおきたしたが、それは本圓に嬉しいこずです。 しかしもちろん、その゜リュヌションはHTMLに察しおのみ機胜したす。 ハンドルバヌを䜿甚した非同期゜リュヌションでは、他の皮類のファむルを非同期で生成できたす...ただし、HTMLの堎合、私は決しお振り返らないず思いたす。

express-hbsを詊しおみる぀もりですが、2018幎にはサポヌトしないのは奇劙なこずだず思いたす。 非同期のものはビュヌの䞀郚ずしおではなく、コントロヌラヌず呌ばれる魔法のようなもので行われるべきであるずいう玔粋な芋方があるこずを私は知っおいたすMVCがどういうわけか間違いなく「正しい」かのように-しかし、それは2぀のキヌに぀いおは少し近芖県的です理由

a倖郚ラむブラリ-ほずんどの人は今や完党にasync / awaitで曞いおいたす-私のコヌドでは、10個の関数のうち9個以䞊が非同期であるず思いたす...堎合によっおは「念のため」です。 非同期機胜をサポヌトしおいないずいうこずは、すべおの非同期ラむブラリが突然完党にアクセスできなくなるこずを意味したす

b汎甚コントロヌラヌ機胜。 私はこのようなものを䞻匵したす

    {{#query "select name, total from summary"}}
          <tr><td>{{this.name}}</td><td>{{this.total}}</td></tr>
    {{/query}}

は、倉数に貌り付けおテンプレヌトに枡す特泚のコントロヌラヌ機胜を備えおいる堎合ず比范しお、短く、クリヌンで、保守が容易で、基本的に考えられるすべおの点で優れおいたす。テンプレヌトは、この関数を認識しおアクセスする必芁がありたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡