dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.5k stars 10.04k forks source link

Enhancements to components #5455

Closed danroth27 closed 5 years ago

SteveSandersonMS commented 6 years ago

Core app model features underway:

Under consideration:

exyi commented 6 years ago

Hi, I don't really like how the component initialization and state management works now. In short - it seems to be too much reflection based. Do you consider redesigning it anyway? Sometimes it seems almost ironic that you have a comment "we could consider removing the 'name equality' check entirely for perf" just before assigning the property by reflection :)

IMO, it would be nicer to have a "component descriptor" that would be able to create a new instance and to update an existing instance (and say if it has been updated) and that would be generated by the Razor compiler. Something like:

private SomeType lastValue_component1_attribute1;
private Descriptor component1 = new Descriptor<MyComponent>(
     create: () => {
            return new MyComponent() {
                  SomeHardcodedAttr = "123"
            }
     },
     update: (component) => {
            bool updated = false;
            var atribute1 = this.Property123; // just get value from closure
            if (attribute1 == lastValue_component1_attribute1) { // no virtual dispatch for comparison
                 component.Attribute1 = lastValue_component1_attribute1 = attribute1;
                 updated = true;
            }
            return updated;
     }
);
void Build(... builder) {
     builder.AddComponent(1, component1);
}

This approach would be much more extensible for alternative component state management approaches. I'm also pretty sure that it would be more performant. While the code might look significantly longer in C#, I'm pretty sure that the difference will not be that dramatic when compiled to MSIL or WASM, and it will also give LLVM much more room for optimizations.

Of course, you could leave the current mechanism as a sugar above this mechanism, noone says that the create functions can't be a Activator.CreateInstance call and the update some foreach with reflection ;)

SteveSandersonMS commented 6 years ago

@danroth27 This is done enough for 0.0.5 so I'm moving it to 0.1.0 now for the remaining items.

AxDSan commented 6 years ago

Is “Controlling whether a parameter is required” the same as “Allowing optional parameters” ? (e.g. @page(“user/{name}/{id}?”)) If so, then I don’t have to open a new enhancement issue.

lohithgn commented 6 years ago

@AxDSan in Blazor i don't think it supports the optional parameter yet... i tried to have an optional indicator "?" but got the below error

Error: System.InvalidOperationException: Invalid template 'feed/{FeedId}?'. Missing '}' in parameter segment '{FeedId}?'.

the way to do this, is to have multiple route definition in the page. For e.g. in my case i wanted "/feed/{FeedId}". the FeedId can be empty. so to handle this situation you will need to have the following route defined in the page

@page "/feed"
@page "/feed/{FeedId}"

hope this helps

AxDSan commented 6 years ago

Yup that's a workaround :D thank you!

Andrzej-W commented 6 years ago

Can someone explain in a few words what is: "Controlling whether arbitrary non-declared parameters can be passed". Why should we have this possibility? What are the benefits?

SteveSandersonMS commented 6 years ago

@Andrzej-W Currently, although component A written in Razor can declare parameters via [Parameter], another component B can pass any arbitrary set of other name-value pairs to A as parameters. No error occurs just because A doesn't have a corresponding [Parameter]. In fact, by overriding OnParametersSet, A can programmatically read the list of supplied name-value pairs. There are good use cases for this (consider a wrapper component around a DOM element that wants to output all name/values supplied as DOM attributes, without listing every possible DOM attribute name). There are other cases where it serves no purpose and would be less confusing if prevented.

AxDSan commented 6 years ago

Quick question, I'm looking through the list of features, but do we have that one thing that allows components to output data back to the parent component? something like Angular maybe like the @output directive? - because [Parameter] is basically our @input() but I don't really see the way of sending data back to a parent component just yet.

SteveSandersonMS commented 6 years ago

@AxDSan Yes, bind (docs). Or manually have the parent pass a callback to the child.

Andrzej-W commented 6 years ago

Thank you @SteveSandersonMS for explanation.

SteveSandersonMS commented 5 years ago

Moving out of the preview3 milestone because nothing specific in this issue is planned for preview 3.

SteveSandersonMS commented 5 years ago

I've moved the "key" item to a new issue at https://github.com/aspnet/AspNetCore/issues/8232

And as for what remains besides that, it's more a list of mostly-outdated ideas than things we're committed to. We can create new issues for anything that still comes up as a requirement.

A moment of contemplation, if you will, as we finally close what was the original issue 1 at https://github.com/aspnet/blazor/issues/1.

rynowak commented 5 years ago

Press F to pay respects