Create an account


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Blazor 0.3.0 experimental release now available

#1
Blazor 0.3.0 experimental release now available

<div style="margin: 5px 5% 10px 5%;"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/06/blazor-0-3-0-experimental-release-now-available.png" width="1277" height="497" title="" alt="" /></div><div><p>Blazor 0.3.0 is now available! This release includes important bug fixes and many new feature enhancements.</p>
<p>New features in this release (details below):</p>
<ul>
<li>Project templates updated to use <a href="https://getbootstrap.com/">Bootstrap 4</a></li>
<li>Async event handlers</li>
<li>New component lifecycle events: <code>OnAfterRender</code> / <code>OnAfterRenderAsync</code></li>
<li>Component and element refs</li>
<li>Better encapsulation of component parameters</li>
<li>Simplified layouts</li>
</ul>
<p>A full list of the changes in this release can be found in the <a href="https://github.com/aspnet/Blazor/releases/tag/0.3.0">Blazor 0.3.0 release notes</a>.</p>
<h3 id="get-blazor-0-3-0">Get Blazor 0.3.0</h3>
<p>To get setup with Blazor 0.3.0:</p>
<ol>
<li>Install the <a href="https://go.microsoft.com/fwlink/?linkid=873092">.NET Core 2.1 SDK</a> (2.1.300-preview2-008533 or later).</li>
<li>Install <a href="https://go.microsoft.com/fwlink/?linkid=873093">Visual Studio 2017</a> (15.7 Preview 5 or later) with the <em>ASP.NET and web development</em> workload selected.</li>
<li>Install the latest <a href="https://go.microsoft.com/fwlink/?linkid=870389">Blazor Language Services extension</a> from the Visual Studio Marketplace.</li>
</ol>
<p>To install the Blazor templates on the command-line:</p>
<pre><code>dotnet new -<span class="hljs-selector-tag">i</span> Microsoft<span class="hljs-selector-class">.AspNetCore</span><span class="hljs-selector-class">.Blazor</span><span class="hljs-selector-class">.Templates</span>
</code></pre>
<p>You can find getting started instructions, docs, and tutorials for Blazor at <a href="https://blazor.net">https://blazor.net</a>.</p>
<h3 id="upgrade-an-existing-project-to-blazor-0-3-0">Upgrade an existing project to Blazor 0.3.0</h3>
<p>To upgrade an existing Blazor project from 0.2.0 to 0.3.0:</p>
<ul>
<li>Install all of the required bits listed above.</li>
<li>Update your Blazor package and .NET CLI tool references to 0.3.0.</li>
<li>Remove any package reference to <code>Microsoft.AspNetCore.Razor.Design</code> as it is now a transitive dependency.</li>
<li>Update the C# language version to be 7.3. You may need to restart Visual Studio for this change to take effect.</li>
<li>Update component parameters to not be public and to add the <code>[Parameter]</code> attribute.</li>
<li>Update layouts to inherit from <code>BlazorLayoutComponent</code> and remove the implementation of <code>ILayoutComponent</code> including the <code>Body</code> property.</li>
</ul>
<p>Your upgraded Blazor project file should look like this:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Project</span> <span class="hljs-attr">Sdk</span>=<span class="hljs-string">"Microsoft.NET.Sdk.Web"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">TargetFramework</span>&gt;</span>netstandard2.0<span class="hljs-tag">&lt;/<span class="hljs-name">TargetFramework</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">RunCommand</span>&gt;</span>dotnet<span class="hljs-tag">&lt;/<span class="hljs-name">RunCommand</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">RunArguments</span>&gt;</span>blazor serve<span class="hljs-tag">&lt;/<span class="hljs-name">RunArguments</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">LangVersion</span>&gt;</span>7.3<span class="hljs-tag">&lt;/<span class="hljs-name">LangVersion</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.Blazor.Browser"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"0.3.0"</span> /&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.Blazor.Build"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"0.3.0"</span> /&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">DotNetCliToolReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.Blazor.Cli"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"0.3.0"</span> /&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">Project</span>&gt;</span>
</code></pre>
<h3 id="project-templates-updated-to-use-bootstrap-4">Project templates updated to use Bootstrap 4</h3>
<p>The Blazor project templates have been updated to use <a href="https://getbootstrap.com/">Bootstrap 4</a>. Bootstrap 4 includes lots of new features including an improved grid system based on flexbox, an improved reset file, new components, better tooltip support, better forms styling, built-in spacing utilities, and much more. </p>
<p>The new Bootstrap 4 styles also give the Blazor templates a fresh look:</p>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/06/blazor-0-3-0-experimental-release-now-available.png" alt="Blazor Boostrap 4 template" /></p>
<h3 id="async-event-handlers">Async event handlers</h3>
<p>Event handlers can now be asynchronous and return a <code>Task</code> that gets managed by the runtime. Once the task is completed the component is rendered without the need to manually invoke <code>StateHasChanged</code>. Any exceptions that occur during the asynchronous execution of the event handler will be correctly handled and reported.</p>
<p>For example, we can update the <em>FetchData.cshtml</em> page to have an Update button that when selected asynchronously updates the weather forecast data by making <code>HttpClient</code> calls to the backend web API:</p>
<pre><code class="lang-csharp">&lt;button <span class="hljs-keyword">class</span>=<span class="hljs-string">"btn btn-primary"</span> onclick=<span class="hljs-string">"@UpdateForecasts"</span>&gt;Update&lt;/button&gt;

...

@functions { WeatherForecast[] forecasts;
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> Task <span class="hljs-title">OnInitAsync</span>(<span class="hljs-params" />) </span>{ <span class="hljs-keyword">return</span> UpdateForecasts(); }
<span class="hljs-function"><span class="hljs-keyword">async</span> Task <span class="hljs-title">UpdateForecasts</span>(<span class="hljs-params" />) </span>{ forecasts = <span class="hljs-keyword">await</span> Http.GetJsonAsync&lt;WeatherForecast[]&gt;(<span class="hljs-string">"/api/SampleData/WeatherForecasts"</span>); }
}
</code></pre>
<h3 id="more-strongly-typed-events">More strongly-typed events</h3>
<p>This release adds strongly typed events for the most of the commonly used browser events, including mouse and focus events. You can now handle most events from your components.</p>
<p>You can see a full list of the events now supported in <a href="https://github.com/aspnet/Blazor/blob/dev/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Rendering/EventForDotNet.ts">here</a>.</p>
<pre><code class="lang-html">&lt;h1 <span class="hljs-keyword">class</span>=<span class="hljs-string">"display-1"</span> onmouseover=<span class="hljs-string">"@OnMouseOver"</span> onmouseout=<span class="hljs-string">"@OnMouseOut"</span>&gt;@inOrOut&lt;/h1&gt;

@functions { <span class="hljs-keyword">string</span> inOrOut = <span class="hljs-string">"OUT"</span>;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">OnMouseOver</span>(<span class="hljs-params" />) </span>{ inOrOut = <span class="hljs-string">"IN!"</span>; }
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">OnMouseOut</span>(<span class="hljs-params" />) </span>{ inOrOut = <span class="hljs-string">"OUT"</span>; }
}
</code></pre>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/06/blazor-0-3-0-experimental-release-now-available-1.png" alt="Mouse events tooling screen shot" /></p>
<p>Most of the event arguments don’t yet capture and surface the <em>data</em> from the events. That’s something that we expect to handle in a future release. We welcome community contributions to help out with this effort.</p>
<h3 id="capturing-references-to-dom-elements">Capturing references to DOM elements</h3>
<p>Blazor components typically interact with the DOM through their rendering logic in markup. There are cases, however, when a parent component needs to modify or interact with DOM elements directly. Example scenarios including setting element focus or integrating with existing UI libraries that require references to elements for initialization. This release adds support for capturing DOM elements from components and using them when interacting with JavaScript.</p>
<p>To capture an element reference from a component attribute the element markup with a <code>ref</code> attribute that points to a component field of type <code>ElementRef</code>.</p>
<pre><code class="lang-html">&lt;input <span class="hljs-keyword">ref</span>=<span class="hljs-string">"username"</span> /&gt;

<span class="hljs-keyword">@functions</span> { ElementRef username;
}
</code></pre>
<p><code>ElementRef</code> is an opaque handle. The <em>only</em> thing you can do with it is pass it through to JavaScript code, which receives the element as an <code>HTMLElement</code> that can be used with normal DOM APIs.</p>
<p>Note that the <code>ElementRef</code> field (<code>username</code> in the previous example) will uninitialized until <em>after the component has been rendered</em>. If you pass an uninitialized <code>ElementRef</code> to JavaScript code, the JavaScript code will receive <code>null</code>.</p>
<p>Let’s create a API that lets us set the focus on an element. We could define this API in our app, but to make it reusable let’s put it in a library.</p>
<ol>
<li>
<p>Create a new Blazor class library</p>
<pre><code> dotnet <span class="hljs-keyword">new</span> <span class="hljs-type">blazorlib</span> -o BlazorFocus
</code></pre>
</li>
<li>
<p>Update <code>content/exampleJsInterop.js</code> to register a JavaScript method that sets the focus on a specified element.</p>
<pre><code class="lang-javascript"> Blazor.registerFunction(<span class="hljs-string">'BlazorFocus.FocusElement'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(element)</span> </span>{ element.focus(); });
</code></pre>
</li>
<li>
<p>Add a <code>ElementRefExtensions</code> class to the library that defines a <code>Focus</code> extension method for <code>ElementRef</code>.</p>
<pre><code class="lang-csharp"> <span class="hljs-keyword">using</span> System; <span class="hljs-keyword">using</span> Microsoft.AspNetCore.Blazor; <span class="hljs-keyword">using</span> Microsoft.AspNetCore.Blazor.Browser.Interop;
<span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorFocus</span> { <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ElementRefExtensions</span> { <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Focus</span>(<span class="hljs-params"><span class="hljs-keyword">this</span> ElementRef elementRef</span>) </span>{ RegisteredFunction.Invoke&lt;<span class="hljs-keyword">object</span>&gt;(<span class="hljs-string">"BlazorFocus.FocusElement"</span>, elementRef); } } }
</code></pre>
</li>
<li>
<p>Create a new Blazor app and reference the BlazorFocus library</p>
<pre><code> dotnet new <span class="hljs-keyword">blazor </span>-o <span class="hljs-keyword">BlazorApp1
</span> dotnet <span class="hljs-keyword">add </span><span class="hljs-keyword">BlazorApp1 </span>reference <span class="hljs-keyword">BlazorFocus</span>
</code></pre>
</li>
<li>
<p>Update <code>Pages/Index.cshtml</code> to add a button and a text input. Capture a reference to the text input by adding a <code>ref</code> attribute that points to a field of type <code>ElementRef</code> with the same name. Add an <code>onclick</code> handler to the first button that sets the focus on the second button using the captured reference and the <code>Focus</code> extension method we defined previously.</p>
<pre><code> <span class="hljs-variable">@using</span> BlazorFocus
...
&lt;button onclick=<span class="hljs-string">"@SetFocus"</span>&gt;Set focus&lt;/button&gt; &lt;input ref=<span class="hljs-string">"input1"</span> /&gt;
<span class="hljs-variable">@functions</span> { <span class="hljs-selector-tag">ElementRef</span> <span class="hljs-selector-tag">input1</span>;
<span class="hljs-selector-tag">void</span> <span class="hljs-selector-tag">SetFocus</span>() { <span class="hljs-selector-tag">input1</span><span class="hljs-selector-class">.Focus</span>(); } }
</code></pre>
</li>
<li>
<p>Run the app and try out behavior</p>
<pre><code> dotnet <span class="hljs-keyword">run</span><span class="bash"> BlazorApp1</span>
</code></pre>
<p> <img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/06/blazor-0-3-0-experimental-release-now-available-2.png" alt="Set focus" /></p>
</li>
</ol>
<h3 id="capturing-reference-to-components">Capturing reference to components</h3>
<p>You can also capture references to other components. This is useful when you want a parent component to be able to issue commands to child components such as <code>Show</code> or <code>Reset</code>.</p>
<p>To capture a component reference attribute the component with a <code>ref</code> attributes that points to a field of the matching component type.</p>
<pre><code class="lang-csharp">&lt;MyLoginDialog ref=<span class="hljs-string">"loginDialog"</span>/&gt;

<span class="hljs-meta">@functions</span> { MyLoginDialog loginDialog;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">OnSomething</span><span class="hljs-params">()</span> </span>{ loginDialog.Show(); }
}
</code></pre>
<p>Note that component references should <strong>not</strong> be used as a way of mutating the state of child components. Instead, always use normal declarative parameters to pass data to child components. This will allow child components to re-render at the correct times automatically.</p>
<h3 id="onafterrender-onafterrenderasync">OnAfterRender / OnAfterRenderAsync</h3>
<p>To capture element and component references the component must already be rendered. Components now have a new life-cycle event that fires after the component has finished rendering: <code>OnAfterRender</code> / <code>OnAfterRenderAsync</code>. When this event fires element and component references have already been populated. This makes it possible to perform additional initialization steps using the rendered content, such as activating third-party JavaScript libraries that operate on the rendered DOM elements.</p>
<p>For example, we can use <code>OnAfterRender</code> to set the focus on a specific element when a component first renders.</p>
<p>The example below shows how you can receive the OnAfterRender event in your component.</p>
<pre><code>&lt;input <span class="hljs-keyword">ref</span>=<span class="hljs-string">"input1"</span> placeholder=<span class="hljs-string">"Focus on me first!"</span> /&gt;
&lt;button&gt;Click me&lt;/button&gt;

@functions { ElementRef input1; <span class="hljs-keyword">bool</span> isFirstRender = <span class="hljs-literal">true</span>;
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnAfterRender</span>(<span class="hljs-params" />) </span>{ <span class="hljs-keyword">if</span> (isFirstRender) { isFirstRender = <span class="hljs-literal">false</span>; input1.Focus(); } }
}
</code></pre>
<p>Note that <code>OnAfterRender</code> / <code>OnAfterRenderAsync</code> is called after each render, not just the initial one, so the component has to keep try of whether this is the first render or not.</p>
<h3 id="better-encapsulation-of-component-parameters">Better encapsulation of component parameters</h3>
<p>In this release we’ve made some changes to the programming model for component parameters. These changes are intended to improve the encapsulation of the parameter values and discourage improper mutation of component state (e.g. using component references).</p>
<p>Component parameters are now defined by properties on the component type that have been attributed with <code>[Parameter]</code>. Parameters that are set by the Blazor runtime (e.g. <code>ChildContent</code> properties, route parameters) must be similarly attributed. Properties that define parameters should <em>not</em> be public.</p>
<p>A <code>Counter</code> component with an <code>IncrementAmount</code> parameter now looks like this:</p>
<pre><code class="lang-html">@page <span class="hljs-string">"/counter"</span>

&lt;h1&gt;Counter&lt;/h1&gt;

&lt;p&gt;Current count: @currentCount&lt;/p&gt;

&lt;button <span class="hljs-keyword">class</span>=<span class="hljs-string">"btn btn-primary"</span> onclick=<span class="hljs-string">"@IncrementCount"</span>&gt;Click me&lt;/button&gt;

@functions { <span class="hljs-keyword">int</span> currentCount = <span class="hljs-number">0</span>;
[Parameter] <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> IncrementAmount { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = <span class="hljs-number">1</span>;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">IncrementCount</span>(<span class="hljs-params" />) </span>{ currentCount += IncrementAmount; }
}
</code></pre>
<h3 id="simplified-layouts">Simplified layouts</h3>
<p>Layouts now inherit from <code>BlazorLayoutComponent</code> instead of implementing <code>ILayoutComponent</code>. The <code>BlazorLayoutComponent</code> defines a <code>Body</code> parameter that can be used for specifying where content should be rendered. Layouts no longer need to define their own <code>Body</code> property.</p>
<p>An example layout with these changes is shown below:</p>
<pre><code class="lang-html">@inherits BlazorLayoutComponent

&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"sidebar"</span>&gt; &lt;NavMenu /&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;

&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"main"</span>&gt; &lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"top-row px-4"</span>&gt; &lt;a href=<span class="hljs-string">"http://blazor.net"</span> target=<span class="hljs-string">"_blank"</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"ml-md-auto"</span>&gt;About&lt;/a&gt; &lt;/<span class="hljs-keyword">div</span>&gt;
&lt;<span class="hljs-keyword">div</span> <span class="hljs-built_in">class</span>=<span class="hljs-string">"content px-4"</span>&gt; @Body &lt;/<span class="hljs-keyword">div</span>&gt;
&lt;/<span class="hljs-keyword">div</span>&gt;
</code></pre>
<h3 id="summary">Summary</h3>
<p>We hope you enjoy this latest preview of Blazor. Your feedback is especially important to us during this experimental phase for Blazor. If you run into issues or have questions while trying out Blazor please <a href="https://github.com/aspnet/blazor/issues">file issues on GitHub</a>. You can also chat with us and the Blazor community on <a href="https://gitter.im/aspnet/blazor">Gitter</a> if you get stuck or to share how Blazor is working for you. After you’ve tried out Blazor for a while please also let us know what you think by taking our in-product survey. Just click the survey link shown on the app home page when running one of the Blazor project templates:</p>
<p><img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/06/blazor-0-3-0-experimental-release-now-available-3.png" alt="Blazor survey" /></p>
<p>Thanks for trying out Blazor!</p>
<p> </p>
</div>
Reply



Forum Jump:


Users browsing this thread:
2 Guest(s)

Forum software by © MyBB Theme © iAndrew 2016