107

最近、ロジックレステンプレートと言われる口ひげに出くわしました。

However, there is no explaining why it is designed in Logic-less way. In another word, what's the advantage of Logic-less template?

4

13 に答える 13

111

つまり、足を撃たれるのを防ぎます。古い JSP の時代には、JSP ファイルに Java コードを散りばめることは非常に一般的でした。コードが分散していたため、リファクタリングが非常に困難でした。

意図的にテンプレートにロジックを入れないようにすると ( mustacheのように)、ロジックを別の場所に配置せざるを得なくなるため、テンプレートは整頓されたものになります。

もう 1 つの利点は、関心の分離という観点から考える必要があることです。コントローラーまたはロジック コードは、UI にデータを送信する前にデータマッサージを行う必要があります。後でテンプレートを別のテンプレートに切り替えた場合 (別のテンプレート エンジンの使用を開始したとします)、移行は簡単です。なぜなら、UI の詳細を実装するだけでよいからです (テンプレートにはロジックがないため)。

于 2011-02-09T14:46:20.363 に答える
68

私の意見では、私はほとんど一人だと感じていますが、私はしっかりと反対の陣営にいます. テンプレートにビジネス ロジックが混在している可能性があるからといって、プログラミング言語の能力をフルに活用しない理由にはならないと思います。

ロジックのないテンプレートの通常の議論は、プログラミング言語に完全にアクセスできる場合、テンプレートに存在しないロジックが混在する可能性があるというものです。これは、ナイフを使うと自分を切ることができるので、スプーンを使って肉をスライスする必要があるという推論に似ていると思います. これは非常に真実ですが、後者を慎重に使用すると、はるかに生産的になります.

たとえば、mustacheを使用した次のテンプレート スニペットを考えてみましょう。

{{name}}:
<ul>
  {{#items}}
    <li>{{.}}</li>
  {{/items}}
</ul>

私はこれを理解できますが、次の (アンダースコアを使用) ははるかに単純で直接的であることがわかります。

<%- name %>:
<ul>
<% _.each(items, function(i){ %>
  <li><%- i %></li>
<% }); %>
</ul>

そうは言っても、ロジックレス テンプレートには利点があることは理解しています (たとえば、変更することなく複数のプログラミング言語で使用できるなど)。これらの他の利点は非常に重要だと思います。私は彼らの論理のない性質がそれらの1つであるとは思わない.

于 2011-05-03T15:27:34.440 に答える
29

口ひげは論理がありませんか?

これではありません:

{{#x}}
  foo
{{/x}}
{{^x}}
  bar
{{/x}}

これにかなり似ていますか?

if x
  "foo"
else
  "bar"
end

そして、それはプレゼンテーションロジック(読む:ほぼ定義)にかなり似ていません

于 2012-10-21T01:30:53.517 に答える
14

ロジックレステンプレートは、埋める方法ではなく、埋めるための穴を含むテンプレートです。ロジックは別の場所に配置され、テンプレートに直接マップされます。この関心の分離は理想的です。なぜなら、テンプレートは異なるロジックで、または異なるプログラミング言語でさえも簡単に構築できるからです。

口ひげのマニュアルから:

ifステートメント、else句、またはforループがないため、これを「ロジックレス」と呼びます。代わりに、タグのみがあります。一部のタグは値に置き換えられ、一部は何も置き換えられず、その他は一連の値に置き換えられます。このドキュメントでは、さまざまなタイプのMustacheタグについて説明します。

于 2010-10-17T21:32:58.883 に答える
13

コインの裏側は、ビジネス ロジックをプレゼンテーションから除外しようと必死になって、モデルに多くのプレゼンテーション ロジックを配置することになります。一般的な例として、「奇数」クラスと「偶数」クラスをテーブルの交互の行に配置する場合があります。これは、ビュー テンプレートの単純なモジュロ演算子で実行できます。ただし、ビュー テンプレートでそれができない場合は、モデル データに奇数または偶数の行を格納するだけでなく、テンプレート エンジンの制限によっては、モデルを汚染する必要さえある場合があります。実際の CSS クラスの名前を使用します。ビューはモデルから完全に分離する必要があります。しかし、Models も View に依存しない必要があります。これは、これらの「ロジックのない」テンプレート エンジンの多くが忘れさせていることです。ロジックは両方の場所にあり、実際には、それがどこに行くかを正しく決定する必要があります。それはプレゼンテーションの問題ですか、それともビジネス/データの問題ですか? 100% 手付かずの景色を見せようとすると、汚染は目立たない別の場所に着陸しますが、同様に不適切です。

反対方向に戻る動きが高まっており、より合理的な中道のどこかに物事が集中することを願っています.

于 2012-11-25T18:19:30.437 に答える
12

これにより、テンプレートがよりクリーンになり、適切に単体テストできる場所にロジックを保持することが強制されます。

于 2010-10-10T03:29:27.000 に答える
9

この会話は、中世の修道士が、ピンの先に何人の天使が収まるかについて議論しているように感じます. 言い換えれば、宗教的で、無駄で、焦点が合っていないと感じ始めています。

小さな暴言が続きます(無視してかまいません):

読み続けたくない場合.. 上記のトピックに対する私の短い応答は次のとおりです。ロジックのないテンプレートには同意しません。私はそれを過激主義のプログラミング形式と考えています。:-) :-)

今、私の暴言は本格的に続いています: :-)

多くのアイデアを極端にすると、結果はばかげたものになると思います。そして時々 (つまり、このトピック) 問題は、私たちが「間違った」考えを極端に取っていることです。

ビューからすべてのロジックを削除するのは「滑稽」であり、間違った考えです。

ちょっと後ろに下がってください。

自問する必要があるのは、なぜロジックを削除するのかということです。コンセプトは、明らかに懸念の分離です。ビューの処理は、ビジネス ロジックから可能な限り分離してください。なぜこれを行うのですか?これにより、ビューを交換することができ (さまざまなプラットフォーム: モバイル、ブラウザー、デスクトップなど)、制御フロー、ページ シーケンス、検証の変更、モデルの変更、セキュリティ アクセスなどをより簡単に交換できます。また、ロジックがビュー (特に Web ビュー) から削除すると、ビューが読みやすくなり、保守が容易になります。私はそれを理解し、それに同意します。

ただし、最優先の焦点は、関心の分離にあるべきです。100% 論理のないビューではありません。ビュー内のロジックは、「モデル」のレンダリング方法に関連している必要があります。私に関する限り、ビューのロジックはまったく問題ありません。ビジネス ロジックではないビュー ロジックを使用できます。

はい、コード ロジックとビュー ロジックをほとんど、またはまったく分離せずに JSP、PHP、または ASP ページを作成した当時、これらの Web アプリケーションのメンテナンスは絶対的な悪夢でした。私が知っていることを信じてください、私はこれらの怪物のいくつかを作成し、次に維持しました. 私が自分と同僚のやり方の間違いを(本能的に)理解したのは、そのメンテナンス段階でした。:-) :-)

したがって、上層部 (業界の専門家) からの布告は、フロントビュー コントローラー (ハンドラーまたはアクションにディスパッチされる [Web フレームワークを選択]) のようなものを使用して Web アプリを構築する必要があり、ビューにコードを含めてはならないというものになりました。 . ビューはばかげたテンプレートになるはずでした。

したがって、私は一般的に、布告の項目の詳細についてではなく、布告の背後にある動機、つまりビューとビジネス ロジックの間の懸念を分離したいという上記の感情に同意します。

私が関わったあるプロジェクトでは、論理のないビューのアイデアを馬鹿げた極端な方法で実行しようとしました。モデル オブジェクトを html でレンダリングできる独自のテンプレート エンジンがありました。それは単純なトークンベースのシステムでした。1つの非常に単純な理由でひどいものでした。ビューで、この小さな HTML のスニペットを表示するかどうかを決定しなければならない場合がありました。..決定は、通常、モデル内の値に基づいて行われます。ビューにまったくロジックがない場合、どうすればよいでしょうか? できません。これについて、私はアーキテクトといくつかの主要な議論をしました。私たちのビューを書いているフロントエンドの HTML 担当者は、これに直面したとき完全に身動きが取れなくなり、そうでなければ単純な目的を達成できなかったため、非常にストレスを感じていました。そこで、テンプレート エンジン内に単純な IF ステートメントの概念を導入しました。その後の安堵と静けさをあなたに説明することはできません. この問題は、テンプレートの単純な IF ステートメントの概念で解決されました! 突然、テンプレート エンジンが改善されました。

では、どうやってこのばかげたストレスの多い状況に陥ったのでしょうか? 私たちは間違った目的に焦点を合わせました。ビューにロジックを含めてはならないというルールに従いました。それは間違っていました。「経験則」は、ビュー内のその量のロジックを最小限に抑えるべきだと思います。そうしないと、不注意にビジネス ロジックがビューに忍び込んでしまう可能性があります。これは、関心の分離に違反します。

「ビューにロジックを入れてはならない」と宣言すると、「良い」プログラマであることを簡単に知ることができると理解しています。(それがあなたの良さの尺度である場合)。上記のルールを使用して、中程度の複雑さの Web アプリを実装してみてください。それほど簡単にはできません。

私にとって、ビューのロジックのルールはそれほど明確ではなく、率直に言って、それが私が望むところです。

ビューに多くのロジックが表示されると、コードのにおいを検出し、ほとんどのロジックをビューから削除しようとします。ビジネス ロジックが別の場所に存在するようにします。懸念事項を分離しようとします。しかし、ビューからすべてのロジックを削除する必要があると言う人々とチャットを始めると、まあ、私には、上記のような状況に陥る可能性があることを知っているので、それは単なる狂信的なものです。

私の暴言は終わりです。:-)

乾杯、

デビッド

于 2013-02-03T16:50:42.437 に答える
6

ロジックレステンプレートについて私が思いついた最良の議論は、クライアントとサーバーの両方でまったく同じテンプレートを使用できるということです。ただし、ロジックレスは必要ありません。独自の「言語」を備えているだけです。私は口ひげが無意味に制限されていると不平を言う人々に同意します。ありがとう、でも私は大きな男の子で、あなたの助けがなくてもテンプレートをきれいに保つことができます。

もう1つのオプションは、クライアントとサーバーの両方でサポートされている言語、つまりnode.jsを使用してサーバー上のjavascriptを使用するテンプレート構文を見つけるか、therubyracerなどを介してjsインタープリターとjsonを使用することです。

次に、haml.jsのようなものを使用できます。これは、これまでに提供されたどの例よりもはるかにクリーンで、うまく機能します。

于 2012-01-22T16:54:41.927 に答える
5

一言で言えば: ロジックレスとは、テンプレート エンジン自体がそれほど複雑ではないことを意味するため、フットプリントが小さくなり、予期しない動作をする方法が少なくなります。

于 2012-05-10T13:16:16.837 に答える
4

質問は古くて答えがありますが、2¢を追加したいと思います(これは暴言のように聞こえるかもしれませんが、そうではありません。制限と、それらが受け入れられなくなったときです)。

テンプレートの目的は、ビジネス ロジックを実行することではなく、何かをレンダリングすることです。テンプレートで必要なことを実行できないことと、テンプレートに「ビジネス ロジック」が含まれていることの間には、紙一重の境界線があります。私は Mustache に対して本当に前向きで、それを使用しようとしましたが、非常に単純なケースで必要なことを行うことができませんでした.

データの「マッサージ」(受け入れられた回答の言葉を使用するため) は、実際の問題になる可能性があります。単純なパスでさえサポートされていません (Handlebars.js が対処するもの)。ビュー データがあり、テンプレート エンジンの制限が大きすぎるために何かをレンダリングするたびに微調整する必要がある場合、これは最終的には役に立ちません。そして、口ひげがそれ自体を主張するプラットフォーム非依存の一部を無効にします。マッサージロジックをどこでも複製する必要があります。

とはいえ、いくつかのフラストレーションの後、他のテンプレート エンジンを試した後、.NET Razor テンプレートに触発された構文を使用する独自の (...さらに別の...) を作成することになりました。これはサーバー上で解析およびコンパイルされ、テンプレートを「実行」するために呼び出すことができる単純な自己完結型の JS 関数 (実際には RequireJS モジュールとして) を生成し、結果として文字列を返します。brad から提供されたサンプルは、私たちのエンジンを使用すると次のようになります (個人的には、Mustache と Underscore の両方に比べて読みやすさがはるかに優れていると思います)。

@name:
<ul>
@for (items) {
  <li>@.</li>
}
</ul>

Mustache でパーシャルを呼び出すときに、別のロジックフリーの制限が発生します。パーシャルは Mustache でサポートされていますが、最初に渡されるデータをカスタマイズすることはできません。したがって、モジュール式のテンプレートを作成して小さなブロックを再利用する代わりに、繰り返しコードを含むテンプレートを作成することになります。

XPath に着想を得た、JPath と呼ばれるクエリ言語を実装することで、この問題を解決しました。基本的に、子へのトラバースに / を使用する代わりにドットを使用します。文字列、数値、ブール値のリテラルだけでなく、オブジェクトと配列もサポートされています (JSON と同様)。この言語には副作用がありません (テンプレート化には必須です) が、新しいリテラル オブジェクトを作成することにより、必要に応じてデータを "マッサージ" できます。

カスタマイズ可能なヘッダーと行のアクションへのリンクを含む「データ グリッド」テーブルをレンダリングし、後で jQuery を使用して動的に行を追加するとします。したがって、コードを複製したくない場合は、行を部分的にする必要があります。そして、レンダリングされる列などの追加情報がビューモデルの一部であり、各行のアクションについても同じである場合、問題が始まります。テンプレートとクエリ エンジンを使用した実際の作業コードを次に示します。

テーブル テンプレート:

<table>
    <thead>
        <tr>
            @for (columns) {
                <th>@title</th>
            }
            @if (actions) {
                <th>Actions</th>
            }
        </tr>
    </thead>
    <tbody>
        @for (rows) {
            @partial Row({ row: ., actions: $.actions, columns: $.columns })
        }
    </tbody>
</table>

行テンプレート:

<tr id="@(row.id)">
    @for (var $col in columns) {
        <td>@row.*[name()=$col.property]</td>
    }
    @if (actions) {     
        <td>
        @for (actions) {
            <button class="btn @(id)" value="@(id)">@(name)...</button>
        }
        </td>
    }
</tr>

JS コードからの呼び出し:

var html = table({
    columns: [
        { title: "Username", property: "username" },
        { title: "E-Mail", property: "email" }
    ],
    actions: [
        { id: "delete", name: "Delete" }
    ],
    rows: GetAjaxRows()
})

ビジネス ロジックは含まれていませんが、再利用可能で構成可能であり、副作用もありません。

于 2011-10-28T17:44:55.920 に答える
3

文字数を含むリストをレンダリングする 3 つの方法を次に示します。最初と最も短いものを除くすべては、ロジックのないテンプレート言語です..

CoffeeScript ( Reactive Coffeeビルダー DSL を使用) - 37 文字

"#{name}"
ul items.map (i) ->
  li i

ノックアウト - 100 文字

<span data-bind="value: name"/>
<ul data-bind="foreach: items">
   <li data-bind="value: i"/>
</ul>

ハンドルバー/口ひげ - 66 文字

{{name}}:
<ul>
  {{#items}}
    <li>{{.}}</li>
  {{/items}}
</ul>

アンダースコア - 87 文字

<%- name %>:
<ul>
<% _.each(items, function(i){ %>
  <li><%- i %></li>
<% }); %>
</ul>

ロジックのないテンプレートの約束は、幅広いスキルセットを持つ人々が自分自身を傷つけることなくロジックのないテンプレートを管理できるということだったと思います. ただし、上記の例からわかるように、最小限のロジック言語を文字列ベースのマークアップに追加すると、結果はより複雑になります。また、昔ながらの PHP を使用しているようにも見えます。

明らかに、私は「ビジネス ロジック」 (広範な計算) をテンプレートから除外することに反対しません。しかし、第一級言語の代わりに疑似言語を表示ロジックに与えることで、代償を払うことができると思います。入力するだけでなく、誰かがそれを読む必要があるコンテキスト切り替えの凶悪な組み合わせ.

結論として、私はロジックのないテンプレートのロジックを理解していないので、それらの利点は私にはゼロだと思いますが、コミュニティの多くの人がそれを異なって見ていることを尊重します :)

于 2014-02-15T05:29:49.027 に答える
2

私はブラッドに同意します:underscoreスタイルは理解しやすいです. しかし、シンタックス シュガーがすべての人を喜ばせるとは限らないことを認めなければなりません。_.each少し混乱する場合は、従来のforループを使用できます。

  <% for(var i = 0; i < items.length; i++) { %>
    <%= items[i] %>
  <% } %>

forまたはなどの標準的な構造にフォールバックできる場合は、いつでも便利ですif<% if() %>or <% for() %>while を使用するだけMustacheで、多少新語を使用if-then-elseできます (ドキュメントを読んでいない場合は混乱します)。

{{#x}}
  foo
{{/x}}
{{^x}}
  bar
{{/x}}

テンプレートエンジンは、ネストされたテンプレートを簡単に実現できる場合に最適です(underscoreスタイル):

<script id="items-tmpl" type="text/template">
    <ul>
        <% for(var i = 0; i < obj.items.length; i++) { %>
            <%= innerTmpl(obj.items[i]) %>
        <% } %>
    </ul>
</script>

<script id="item-tmpl" type="text/template">
    <li>
        <%= name %>
    </li>
</script>

var tmplFn = function(outerTmpl, innerTmpl) {
    return function(obj) {
        return outerTmpl({obj: obj, innerTmpl: innerTmpl});
    };
};

var tmpl = tmplFn($('#items-tmpl').html(), $('#item-tmpl').html());
var context = { items: [{name:'A',{name:'B'}}] };
tmpl(context);

基本的に、内部の tmpl をコンテキストのプロパティとして渡します。そしてそれに応じてそれを呼び出します。甘い :)

ところで、テンプレート エンジンだけに関心がある場合は、スタンドアロンのテンプレート実装を使用してください。縮小するとわずか 900 文字です (4 つの長い行):

https://gist.github.com/marlun78/2701678

于 2014-02-15T11:02:51.407 に答える