Commit Graph

2 Commits

Author SHA1 Message Date
Ryan Nowak d4cbb86f46 Add Support for Templated Components (#1404)
* Test namespace cleanup

* Add recognication for RenderFragment in tag helpers

* Remove dead code from node writers

* refactor type check

* Continue to treat child content as a delegate in codegen

* Add extension to enumerate child content

* Reorganize code generation tests

These were growing a bit disorganized, and weren't really result in good
code reuse.

* fix test base class

* Add some child-content tests

* Add an explicit node for ChildContent

Adds a strongly typed node to represent a 'ChildContent' and what it
contains. This allows us to simplify the code generation path,
detect/processes more issues in IR passes, and will be essential for
supporting multiple child content.

* Ignore ChildContent in components when it's just whitespace

* Add diagnostic for duplicate child content

* Add support for explicit child content elements

Precursor to support for multiple child content items

* Add support for multiple child-content elements

* Change delegate signature for RenderFragment<T>

* Clean up Tag Helper constants

* Allow RenderFragment<T> as a child content

* Allow renaming the template parameter

* Improve error message for invalid child content

* Add diagnostic for repeated child content parameter names
2018-09-10 18:59:51 -07:00
Ryan Nowak c97cb8c18b Add support for Razor templates
Adds support for Razor templates and RenderFragment<T>.

Razor templates are a little-known Razor feature that looks like:
```
@<tag>....<tag>
```

It's so little known that it's not even covered in our docs, but it's
been around for many many years. This features hasn't been implemented
until now for Blazor, and this feature brings it back as a build
building block for templated components (more to come).

In Blazor land a template like:
```
@{ RenderFragment<Person> template = @<div>@item.Name</div>; }
```

complies to code like:
```
RenderFragment<Person> template = (__builder, item) =>
{
    __builder.OpenElement(...);
    ...
    __builder.CloseElement(...);
}
```

Since the declaration always has a generic type parameter inside, it
needs to be in a context where the type is known.. ie: not with `var`.

See tests for ways to consume templates.

NOTE: There are the following caveats for templates
- Templates require a single root element.
- Templates don't work in the `@functions { }` block

These limitations are baked into the core of Razor and will take a while
for us to address (v3.0).
2018-08-31 19:10:42 -07:00