Page 52 - MSDN Magazine, March 2019
P. 52
In the present implementation, the toggle element is styled through a public property named Class. The content of the button is captured through a templated property named ChildContent. Note that in Blazor, a template property named ChildContent automatically cap- tures the entire child markup of the parent element. Also, a template property in Blazor is a property of type RenderFragment.
The interesting thing in the previous source code is the binding to the cascading values. You use the CascadingParameter attribute to decorate a component property, such as OutermostEnv. The property is then populated with cascaded values from the inner- most level. As a result, OutermostEnv takes the value assigned to the instance of ModalContext freshly created in the Init method of the root component (refer back to Figure 2).
In the Toggle component, the Id cascaded value is used to set the value for the data-target attribute. In Bootstrap jargon, the data-target attribute of a dialog toggle button identifies the ID of the DIV to be popped up when the toggle is clicked.
The Content of the Modal Dialog
A Bootstrap dialog box is made of up to three DIV blocks laid out vertically: header, body and footer. All of them are optional, but you want to have at least one defined in order to give users some minimal feedback. A templated component is the right fit here. Here’s the public interface of the Content component as it results from the Content.cshtml file:
@functions {
[CascadingParameter] ModalContext OutermostEnv { get; set; } [Parameter] RenderFragment HeaderTemplate { get; set; } [Parameter] RenderFragment BodyTemplate { get; set; } [Parameter] RenderFragment FooterTemplate { get; set; }
The OutermostEnv cascaded parameter will bring the data defined outside the realm of the Content component. Both the ID and AutoClose properties are used here. The Id value is used to identify the outermost container of the dialog box. The DIV
Figure 4 Markup of the Content Component
signed with the ID will pop up when the modal is triggered. The AutoClose value, instead, is used to control an IF statement that decides whether or not a Dismiss button should go in the header bar.
Finally, three RenderFragment template properties define the actual content for customizable areas—header, footer and body.
As you can see in Figure 4, the Content component does most of the work to render the expected Bootstrap markup for modal dialog boxes. It defines the overall HTML layout and uses tem- plate properties to import the details of the markup that would make a given dialog unique—the header, footer and body markup. Thanks to Blazor templates, any actual markup can be specified as inline content in the caller page. Note that the source code of the caller page (called Cascade in the sample application) is depicted back in Figure 3.
More on Cascading Values and Parameters
Cascading values solve the problem of effectively flowing values down the stack of subcomponents. Cascading values can be defined at various levels in a complex hierarchy and go from an ancestor component to all of its descendants. Each ancestor element can define a single cascading value, possibly a complex object that gathers together multiple scalar values.
To make use of cascaded values, descendant components declare cascading parameters. A cascading parameter is a public or pro- tected property decorated with the CascadingParameter attribute. Cascading values can be associated with a Name property, like so:
<CascadingValue Value=@Context Name="ModalDialogGlobals"> ...
</CascadingValue>
In this case, descendants will use the Name property to retrieve the cascaded value, as shown here:
[CascadingParameter(Name = "ModalDialogGlobals")] ModalContext OutermostEnv { get; set; }
When no name is specified, cascading values are bound to cas- cading parameters by type.
Wrapping Up
Cascading values are specifically designed for hierarchical com- ponents, but at the same time hierarchical (and templated) components are realistically the most common type of Blazor components that developers are expected to write. This article demonstrated cascading parameters and templated and hierarchi- cal components, but also showed how powerful it could be to use Razor components to express specific pieces of markup through a higher-level syntax. In particular, I worked out a custom markup syntax to render a Bootstrap modal dialog box. Note that you can achieve the same in plain ASP.NET Core using tag helpers or HTML helpers in classic ASP.NET MVC.
The source code for the article is available at bit.ly/2FdGZat. n
Dino Esposito has authored more than 20 books and 1,000-plus articles in his 25-year career. Author of “The Sabbatical Break,” a theatrical-style show, Esposito is busy writing software for a greener world as the digital strategist at BaxEnergy. Follow him on Twitter: @despos.
thanks to the following Microsoft technical expert for reviewing this article: Daniel Roth
}
<div class="modal" id="@OutermostEnv.Id"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">
@HeaderTemplate </h5>
@if (OutermostEnv.AutoClose) {
<button type="button" class="close" data-dismiss="modal">
<span>×</span> </button>
} </div>
<div class="modal-body"> @BodyTemplate
</div>
<div class="modal-footer"> @FooterTemplate
</div>
</div> </div>
</div>
46 msdn magazine
Cutting Edge