Directive attributes is our term for built-in compiler features that look-like attributes, but don't map to any real HTML attributes or component parameters.
For instance ref
looks like an attribute, but it does something that's intrinsic to the Razor language.
<!-- Define a field called myButton and assign a reference to the element -->
<button ref="myButton">...</button>
You can think of these like macros.
We want to build a syntax for directive attributes (bind
, onclick
, ref
) that allows more flexibility and can express more complex things than what we currently support. We are currently limited to the kinds of things tag helpers support.
It would also be good to make these built-ins distinct in tooling and syntax from normal attributes.
Design notes are here: https://gist.github.com/rynowak/f2e6a4bfc3b685d7dce15d96942aa4b8
These are my raw notes and discussions with a few others so you may find things that are out of date there. When we ship preview 6 the docs will contain the authoritative info. Read my notes if you want to understand more of the motivations and minor decision points.
Directive attributes are defined as:
@{directive}(-{suffix}?)(:{name})(="{value}")
Examples:
<!-- directive -->
<div @directive>...</div>
<div @directive="value"></div>
<!-- directive with key/value arg-->
<div @directive:key>...</div>
<div @directive:key="value"></div>
<!-- directive with suffix -->
<div @directive-suffix></div>
<div @directive-suffix="value"></div>
<!-- directive with suffix and key/value arg-->
<div @directive-suffix:key></div>
<div @directive-suffix:key="value"></div>
Our built in directives: bind
, onclick
(and other event handlers), ref
and key
are being updated to make use of these new features. Most of the use cases are as simple as before.
You'll notice how some of the parts that are defined by the syntax are used by these updated directives.
Key
<div @key="id">...</div>
Ref
<button @ref="myButton">...</button>
Event Handlers
We wanted to make C# event handlers distinct from JS event handlers. It seems really tricky that a normal HTML attribute would do much more complicated things based on the value that's passed in. Also we're going to end up using more of the directive attribute features as we add power to event handlers.
<button @onclick="Clicked">Click me!</button>
<button @onclick="Clicked" @onclick:stopPropagation>Click me!</button>
note: we haven't implemented stopPropagation
yet, but you can see that we have more options now.
Bind
<input @bind="myValue">...</input>
<input @bind="myValue" @bind:event="oninput" @bind:format="mm/dd">...</input>
<MyButton @bind-Value="myValue">...</input>
Extensibility of any kind.
bind:event
, bind-value:format
etc)bind:event
, bind:format
)bind:event
, bind:format
)@
prefix for directive attributesDoes this mean being able to do things like *ngIf="" which only render components based on some condition?
Indeed, we saw the problem on the validation feature : if you want to add an attribute you have to subclass the one offered by the framework.
But I think we should keep it to feature like this (adding behavior to an html tag) and don't apply it to feature already present in razor (if/for ...) which is a not very beautiful in angular IMHO.
The good thing about it is the ability to reduce nesting and in some ways make it more elegant to read. But I'm sure the right design will come for blazor with time so i have no worries for that.
Thats exactly what I need in Blazor!
Check list for the platform agnostic/VS windows work:
I have the majority of this done in bulk on my box. In order to get things done in batches going to break it all up into the above pieces to be easily consumable
VS Windows work has been mostly completed, waiting on two partner teams to get their bits to make it 100%. Starting VSCode work to get directive attribute support.
VSCode support in PR: https://github.com/aspnet/Razor.VSCode/pull/367
VSCode has been updated and insertion should be complete soon.
Most helpful comment
Indeed, we saw the problem on the validation feature : if you want to add an attribute you have to subclass the one offered by the framework.
But I think we should keep it to feature like this (adding behavior to an html tag) and don't apply it to feature already present in razor (if/for ...) which is a not very beautiful in angular IMHO.