Ich versuche, dieses Tutorial über die Implementierung von Facebooks BigPipe zu aktualisieren.
Es gibt eine HTML-Helfer-Erweiterung, die einer Liste ein Pagelet hinzufügt und dann ein Halte-Div an die Antwort ausgibt. Die Idee ist, dass der Inhalt dieser Seite später zu einer Zeichenkette gerendert und dann per Javascript in diese Holding Div injiziert wird.
public static void RegisterPagelet(this HtmlHelper helper, Pagelet pagelet) {
var context = helper.ViewContext.HttpContext;
List<Pagelet> pagelets = (List<Pagelet>)context.Items["Pagelets"];
if (pagelets == null) {
pagelets = new List<Pagelet>();
context.Items["Pagelets"] = pagelets;
}
pagelets.Add(pagelet);
context.Response.Write("<div id=\"" + pagelet.Container + "\"></div>");
}
Im Beispiel heißt diese Funktion wie folgt:
<div id="textHolder">
<% Html.RegisterPagelet(myPagelet); %>
</div>
Dadurch wird das Pagelet zu den Listen hinzugefügt und die Holding Div an den Antwortstream ausgegeben.
So
<div id="textHolder">
<div id="pageletPlaceHolder"></div>
</div>
Wenn ich jedoch dasselbe in Razor versuche:
<div id="textHolder">
@{ Html.RegisterPagelet(myPagelet); }
</div>
Der div-Platzhalter wird am oberen Rand des Texts außerhalb von textHolder div angezeigt. Warum ist das? Wie kann ich erreichen, dass sich dies wie in der Webforms-Ansicht verhält, in der die Antwort im div ausgegeben wird?
Vielen Dank.
Eine Razor-Ansicht wird von innen nach außen gerendert. Grundsätzlich werden Inhalte in temporäre Puffer geschrieben, die in den Antwortstrom geschrieben werden, wenn die oberste Layoutseite erreicht ist. Wenn Sie also direkt von Ihrer HtmlHelper-Erweiterung in den Antwort-Stream schreiben, wird dieser in der falschen Reihenfolge ausgegeben.
Die Lösung ist zu verwenden:
helper.ViewContext.Writer.Write("<div id=\"" + pagelet.Container + "\"></div>");
Ändern Sie Ihre Methode so, dass sie nicht ungültig ist, sondern MvcHtmlString zurückgibt
public static MvcHtmlString OutputText(this HtmlHelper helper, string text) {
return New MvcHtmlString(text);
}
Verwenden Sie dies wie gewohnt
<div id="textHolder">
@Html.OutputText("FooBar");
</div>
Die Idee ist von der Tatsache inspiriert, dass fast jede Eingabe- (und andere) Erweiterungsmethode in MVC MvcHtmlString zurückgibt.
Sie sollten den ViewBag verwenden und den String dort einfügen und dann ausgeben.
Im Controller:
ViewBag.Foo = Bar;
Im Hinblick auf:
<div>
@ViewBag.Foo
</div>