FAQ
この API の形から生じる疑問と、その答えがどこで決まっているかです。
VStack や .Padding() や Text() が無いのはなぜですか#
コードファーストにも種類があり、この API はその種類ではないからです。この API は HTML を写します。書いた要素はそのまま出る要素で、レイアウトは CSS が担い、文字列をそのまま書けばテキストノードです。
HTML とは別の名前を用意すると、それを覚え、描画がおかしいときは HTML へ読み替え、HTML と CSS が変わるたびに保守する必要が出ます。どの系譜に連なるのか、なぜ SwiftUI の系譜を採らなかったのかは
DESIGN.md §4.1 にあります。
.razor ファイルを残せますか#
残せます。.razor ファイルは BlazorCodeFirst のコンポーネントを通常のタグとして書けます。
BlazorCodeFirst のコンポーネントも Component<T>() で .razor コンポーネントを呼べます。
制限は同一プロジェクトの場合だけです。Component<T>() は、同じプロジェクトで宣言された .razor
の型を指定できません。ソースジェネレーターは互いの出力を見られないからです(BCF3012)。参照プロジェクトにある同じコンポーネントは通常どおり解決します。コンポーネントと再利用を読んでください。
MudBlazor や Radzen などのコンポーネントライブラリと一緒に使えますか#
使えます。どれも参照アセンブリにある通常の Blazor コンポーネントで、Component<T>() はまさにその場合のためにあります。パラメーターは .Param、テンプレートは .Template、子の内容は角括弧です。
実行時のコストはどれくらいですか#
.razor コンポーネントと変わりません。ジェネレーターが出すのは、シーケンス番号を静的に振った
RenderTreeBuilder のメソッドで、これは Razor コンパイラが出すものと同じです。
実行時の UI ツリーはなく、リフレクションもなく、式のコンパイルもありません。コンポーネントを書いた設計時の API は配布物に残りません。IL トリマーが削ります。
クラスが partial かつトップレベルでなければならないのはなぜですか#
partial なのは、ジェネレーターが描画をそのクラスへ書き込むからです(BCF1001)。トップレベルなのは、入れ子のクラスを生成ファイル側で開き直すには、外側の型の宣言を型引数まで含めて書き直さねばならないからです(BCF1005)。
Body の中で通常の if や foreach を書けないのはなぜですか#
それぞれが専用のシーケンス空間を必要とするからです。このコンパイルの要点は、テンプレートのどの位置にもビルド時に番号が振られることです。If と ForEach は、その空間を明示した同じ制御構文です。
ゲッターが返すのは1つの式で、その手前にローカル変数を置けます(はじめに)。本体がどうしてもその形にならないなら、RenderView を手で書いてください。
ForEach がキーを要求するのはなぜですか#
位置で差分を取るリストは、並び替わった瞬間に別の要素の状態を使い回すからです。そしてそれは、利用者が入力の移動に気づくまで見えません。パラメーターに既定値はないので、リストは項目を識別するか、key: null と明示して代償を引き受けるかのどちらかです(キーを使わない)。
Raw は安全ですか#
信頼できる内容に限って安全です。エスケープせずに DOM へ書きます。Razor の MarkupString と同じです。利用者の入力や外部の応答を通してはいけません(Raw)。
ビルドが止まったが ID に見覚えがない#
どの診断もリファレンスに項があり、そこに意味と、代わりに書くコードがあります。ビルドが ID を表示するので、そのページをその ID で検索してください。
書いたものと違う描画になったら、どこを見ますか#
それは、このコンパイラが防ぐために作られている事態です。まず診断を見てください。違うものを出す代わりに、翻訳できないことを報告する作りです。何も出ていないなら、書いた式と期待した HTML のあいだに差があります。その対応は要素と装飾に書いてあります。