Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate .NET 7 @bind get/set/after modifiers #774

Closed
egil opened this issue Jun 25, 2022 · 5 comments
Closed

Investigate .NET 7 @bind get/set/after modifiers #774

egil opened this issue Jun 25, 2022 · 5 comments
Labels
investigate This issue require further investigation before closing.

Comments

@egil
Copy link
Member

egil commented Jun 25, 2022

There is a new feature coming in in .NET 7 related to @bind that we might need to update bUnit to support, more details here: dotnet/aspnetcore#39837.

@egil egil added the investigate This issue require further investigation before closing. label Jun 25, 2022
@egil egil changed the title Ensure support for Bind get/set/after modifiers Investigate .NET 7 @bind get/set/after modifiers Jun 25, 2022
@linkdotnet
Copy link
Collaborator

Ahh nice. As this is merged it should be included in the nightly builds, so we can check easily what is done under the hood.

TBH: I am not sure where @bind:after differs from OnParametersSetAsync.

@egil
Copy link
Member Author

egil commented Jun 25, 2022

TBH: I am not sure where @Bind:after differs from OnParametersSetAsync.

I haven't deep-dived into this feature yet either.

@linkdotnet
Copy link
Collaborator

I just checked out the latest nightly and I don't think the compiler part is in yet (was merged 4 days ago). I set a breakpoint and console output in the after part and never saw any of it.

Given the example in the PR my output is this:

__builder.AddAttribute(1, "@bind:after", "PerformSearch");

When checking this the expected outcome is something like this:

async __value => { ParentValue = __value; await global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.InvokeAsynchronousDelegate(Update); });

But for sure that will be part of Preview 7.

@linkdotnet
Copy link
Collaborator

linkdotnet commented Jul 23, 2022

After investing further: I am not sure if there is anything to do for us. This is a pure compiler / consumer feature. Nothing for anyone to implement.

Even if we have a person offering a component with @bind then there is nothing to implement to make @bind:after work. So if we have something like this:

<button @onclick="() => Value++"></button>

@code {
    private int _value;

    [Parameter]
    public int Value
    {
        get => _value;
        set
        {
            if (_value != value)
            {
                _value = value;
                ValueChanged.InvokeAsync(_value);
            }
        }
    }

    [Parameter]
    public EventCallback<int> ValueChanged { get; set; }
}

With a consumer like that:

<BindCustom @bind-Value="a" @bind-Value:after="UpdateInvokeCounter"></BindCustom>

@code {
	private int a;
	public int InvokeAfterCount { get; set; }

	private void UpdateInvokeCounter()
	{
		InvokeAfterCount++;
	}
}

Then, as Todd Howards would say: "It just works". All compiler "magic". I mean good for us ;) Let me know your thoughts.

The next part is just the original message I wrote initially.


Original Post:

Just a had a small look into that feature. And for bind:after basically we could extend our already existing Bind method with optional overload where the user can pass in after action. That is more than trivial.

I would make a small PR for that. That tackles the problem at least to some extend. Is it fine if I make the PR targeting v2 and we back-port if necessary? The get and set part will be done separately (they are easy workarounds to make it work even today)

Small detail why we have bind:after in contrast to OnParameterSet. OnParameterSet is only called when the parent component updated the variable (or on the first render cycle). bind:after is called everytime when a variable, which the component owns, changes.

If you have a input: <input @Bind="myVar" @Bind:after="() => Console.Write(HelloWorldString)" />
Everytime you type in something, the after event will fire.

Any thoughts / objections? @egil

@egil
Copy link
Member Author

egil commented Jul 24, 2022

Great work. If it just works then lets close this for now. If it turns out there are corner cases we need to handle, it can always be reopened.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
investigate This issue require further investigation before closing.
Projects
None yet
Development

No branches or pull requests

2 participants