Razor components vs View Components - asp.net-core

I recently upgraded from Asp .NET Core 2.2 to 3.1 and can use Razor Components in razor pages. They look basically like View Components except it uses blazor and everything on the same file. I tried to search but i haven't read anything on documentation that says to use Razor Components instead View Components.
So here is the question...
What is the point of using Razor Components instead View Components in Razor Pages? Is it better? I know View Components are a bit painful to set because you have to set a default view and a code behind file with the logic and you cannot use javascript on it, only on the parent view. Most of my apps are full of View Components and I was wondering what are the advantages of switching to razor components?

While View Components are more like partial views but asynchronous, DI friendly, and kind of independent. They are mostly for view-only purposes (yeah it's possible to add some update logic via AJAX but it's more like a hack rather than a feature) and are used mostly to re-use common UI units like navigation, login block, sidebar, etc.
Razor Components are sort of "full featured" UI components, which can be easily nested, pass parameters through the components hierarchy, raise and handle UI events, and so on. So you can easily use them to manage your app UI, or even create custom UI component libraries.

Related

Can I use blazor component tags in razor pages?

I know I can render blazor component anywhere inside razor page using
Html.RenderComponentAsync() or <component type="typeof(Client.App)" render-mode="Static">
What I would like to achieve is being able to use regular blazor tag components with their ability to nest them with RenderFragment, for example:
<OutsideComponent>
<InsideComponent>
<div>Some content</div>
</InsideComponent>
</OutsideComponent>
At the same time I would like to keep all razor page functions like OnGet(), OnPost() handles.
Is that at all possible to merge those two approaches? I use render-mode="Static" and don't care about blazor interactivity, I just want my code separated to nestable components.

Nested ViewComponent, is it possible?

Trying to implement the layout of the picture below, I would like to ask about best practices regarding the architecture of the page layout. Is it better to have independent ViewComponents in every section of the page or partial views? Is it possible to have nested ViewComponents?
The idea is to reuse the sections in other positions in different pages. The concept is very similar to Web parts we used to have but now I try to implement something like this with Asp. Net Core.
Yes, it is possible to have nested View Components.
What is important to keep in mind:
You should keep your views structure under Components folder plain
You should keep your ViewComponent classes under ViewComponent folder plain
You should control infinite loops yourself when you nest component1 into component2 and at the same time component2 into component1
NOTE: most likely you will need your components to include edit/save/update functionalities. As far as I understand, View Components are supposed to be views only as they have only InvokeAsync and not something like UpdateAsync. So if you'd like to implement any kind of saving logic, you will need to take care of doing this yourself (e.g. via AJAX calls). It is possible (I have verified), but it requires to get familiar with Microsoft.jQuery.Unobtrusive.Ajax and handle responses on the client side in JavaScript (sometimes including things like replacing in JS the DOM element inner HTML with what you get from the server response). You will also need to decide where to put controller actions for view component update endpoints (could be a special Controller class for View Components).

Advanced Mobile View

I use Bootstrap for responsiveness. But my client likes the mobile view of https://www.konga.com
How is this achieved, or what kinda framework is used for this, or is it an app embedded into the website?
This can be achieved by using bootstrap grid layout with custom styling. There cannot be a framework for such requirements. Bootstrap framework provides the initial base for developing UI elements, rest can be easily customized using Normal CSS styles that depends on designer

How can I embed a twitter timeline in a Durandal view?

The code to embed the widget is nice and simple, but it includes javascript in tags.
Durandal appears to strip out such script tags.
How do I use the embed code in a Durandal view?
https://dev.twitter.com/web/embedded-timelines
<a class="twitter-timeline" href="https://twitter.com/XXX" data-widget-id="XXX">Tweets by #XXX</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
You would need to write a custom Knockout binding, or create a Durandal widget where the view is your tag, and the viewModel handles the JavaScript in your tag.
Some notes: In your widget's view model, you would avoid d.getElementsByTagName(s) in favor of simply referencing the view reference passed in to either the attached or compositionComplete handler that Durandal provides. In fact, you could pretty much eschew all direct DOM manipulation in favor of Durandal's imported view references and Knockout's/Durandal's templating/composition.
UPDATE
Take a look at this from the documentation you reference: "If you’re already including our ‘widgets.js’ JavaScript in your page to show embedded Tweets or Twitter buttons, you don’t need to include this script again; it updates automatically to support new features."
This could lead you down the path of simply referencing widgets.js in a script tag in your index.html or index.chtml file.
You cannot use script tags in Durandal views, but you can use them in your index page.
SECOND UPDATE
Once widget.js has been referenced in a script tag in the index.html or index.chtml (or perhaps even by using AMD), it becomes a matter of choosing the proper Durandal point at which to load the Twitter widget. This could be either in the attached handler or in the compositionComplete handler, as indicated above.
As the OP pointed out in his comments, a functional place to do this is compositionComplete, in the following manner:
var compositionComplete = function () {
twttr.widgets.load();
}
as documented here.
This assumes that twttr is either on the window or injected into the viewModel.
POSSIBLE MEMORY LEAK
It is equally important to note that unloading of widgets must take place in the Durandal's detached handler. Use Twitter's API to unload, and then be sure to nullify the windows reference.

Using TagHelpers vs ViewComponents in ASP.NET MVC6

I'm trying to understand the use case differences between TagHelpers and ViewComponents in asp.net 5 because the end result functionality seems very similar. We have TagHelpers that can create new HTML tags that get parsed by the Razor engine and then ViewComponents that get explicitly invoked. Both return some HTML content, both are backed by their respective base classes, both have async versions of methods they can implement to get their work done.
So when would one be used over another? Or am I missing some information?
There's definitely some conceptual overlap between TagHelpers and ViewComponents. TagHelpers are your utility to work with HTML where ViewComponents are your way to stick to C#, do isolated work and then spit out HTML. I'll go into each in detail:
ViewComponents
Your conceptually equivalent mini-controller; you will see that many of the methods/properties that ViewComponents expose are very familiar to those that exist on a Controller. Now as for invoking ViewComponents, that's more equivalent to utilizing HTML helpers (one thing TagHelpers make better). To sum up ViewComponents: Their primary purpose is to feel like a controller, stay in C# land (there may be no need to add utility to HTML), do smaller/isolated work and then spit out stringified HTML.
TagHelpers
A utility that enables you to work along side existing HTML or create new HTML elements that modify what happens on a page. Unlike ViewComponents TagHelpers can target any existing HTML and modify its behavior; example: you could add a conditional attribute to all HTML elements that would conditionally render the element server side. TagHelpers also allow you to intermingle common HTML terms, ex:
<myTagHelper class="btn">Some Content</myTagHElper>
As you can see we're adding a class attribute to our TagHelper just as if it were HTML. To do this in ViewComponents, you'd need to pass in a dictionary of attributes or something equivalent (unnatural). Lastly multiple TagHelpers can run over a single HTML element; each having their own stage at modifying output (allows entry for modular TagHelper toolkits). To sum TagHelpers up: They can do anything that ViewComponents can do and more BUT do not feel familiar to things like Controllers that ASP.NET developers are used to; also some projects may not want to intermingle server side HTML.
Extra:
I recently did a video showcasing the benefits of TagHelpers. Basically a walk through of what they're good at and how to use them. You can watch it here.
When deciding which one to use I always consider how complex the HTML of the component will be.
If it's something simple like a tree view or a pager
<ul class="jstree">
<li>Node 1</li>
<li>...</li>
</ul>
That is candidate for tag helper, because it's simple. Large HTML in a C# code would be hard to maintain.
On the other hand if it's complex HTML with many divs, images and configuration like a full blown menu where it can be vertical or horizontal that's your view component. Benefit of view component is that you can use multiple views so for menu so you can separate horizontal.cshtml & vertical.cshtml while reusing same backend code.
Turns out that in .Net Core 1.1, you can call a ViewComponent using the tagHelper syntax.
Regarding Taylor's comment "Their primary purpose is to feel like a controller", it is true, but since you cannot directly call this "micro-controller" directly, the "controller-like" behavior is limited in that you can only create a part of a page, you cannot call it again (say via an ajax call, an Edit Action, etc).
One primary difference between TagHelpers and ViewComponents relates to how much work needs to be done by the object. TagHelpers are fairly basic, requiring only a single class that overrides the Process method to produce the output of the TagHelper. The downside is that if you do any complex work to create inner HTML in the TagHelper, it has to all be done in code. In a ViewComponent, you have a mini-controller capable of doing a lot more work, plus it returns a view, where you have actual Razor syntax code that can be mapped to a model.
Another post mentioned that ViewComponents are more "HTML Helper"-y in how you call them. ASP.NET 1.1 addressed that issue, so that you can call it with
<vc:view-component-name param1="value1" param2="value2></vc:view-component-name>
For most purposes, a TagHelper has a definite advantage, because it's easier. But if you need a more robust solution, ViewComponent is the way to go.
And yet something that kind of defeats the purpose of View Components (IMHO) is that from the View Component class there seems to be no way to access the Inner Html of the VC if you use the tag helper syntax:
<vc:MyComponent id="1" att="something">
Some HTML markup you would not want to put in an attribute
</vc:MyComponent>
There are however good applications of a VC such as the Bootstrap Navigation Bar View Component I saw in a TechieJourney blog post.