Aspnetcore: Implement *directive attribute* feature for components

Created on 4 Jan 2019  路  8Comments  路  Source: dotnet/aspnetcore

Summary

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.

Changes and design notes

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>

Out of scope

Extensibility of any kind.

Implementation steps:

  • [x] Support for parameters in the compiler (bind:event, bind-value:format etc)
  • [ ] Completion support

    • [x] VS



      • [x] Support for directive attribute completion


      • [x] Support for parameter completion (bind:event, bind:format)



    • [x] VS Code



      • [x] Support for directive attribute completion


      • [x] Support for parameter completion (bind:event, bind:format)



  • [x] Support for the @ prefix for directive attributes
  • [x] Update all existing compiler intrinsic attributes (bind, ref, event handlers etc)
  • [ ] Update documentation and samples
  • [x] Update templates
Components Big Rock Done L area-blazor enhancement feature

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.

All 8 comments

Does 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:

  • [x] Enable completion facts service to take code documents. Directive attribute completion will need more information than just the SyntaxTree. PR
  • [x] Update completion facts service to work off a provider model. Completions will be coming from multiple different sources and in order to build a system that works in both VSCode, VSWindows and VSMac we need the ability to toggle certain types of completions on and off easily. PR
  • [x] Fix Razor directive completions to be more explicit for when they apply so we don't end up providing directive completions for directive attributes when they're enabled. PR
  • [x] Integrate with Ajay's changes
  • [x] Add support for transitioned directive attributes PR
  • [x] Add support for parameter directive attributes PR

    - [x] Add support for directive attributes + parameter descriptions PR

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 has been updated and insertion should be complete soon.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FourLeafClover picture FourLeafClover  路  3Comments

groogiam picture groogiam  路  3Comments

ipinak picture ipinak  路  3Comments

fayezmm picture fayezmm  路  3Comments

rbanks54 picture rbanks54  路  3Comments