mko
mko

Reputation: 7325

Different method calls in Blazor

I am experimenting with Blazor for some time now and I am trying to find an explanation about the difference between

<input type="button" onclick="@methodCall()">Something</button>

and

<input type="button" @onclick="() => methodCall()">Something</button>

Why is @ expected before onclick vs @ being part of value?

Upvotes: 2

Views: 4407

Answers (3)

Henk Holterman
Henk Holterman

Reputation: 273179

Why is @ expected before onclick vs @ being part of value?

  1. onclick without an @ is not what you usually want but it is valid. The value should then be JavaScript.

This works:

// razor
<button type="button" onclick="@MethodCall()">Something</button>

// c#
string methodCall() => "alert()";

In this sample the C# methodCall returns some JavaScript. You need the @ in "@MethodCall()" because JS is text.

2.

What you probably want here is

// razor
<button type="button" @onclick="MethodCall">Something</button>

After @onclick Blazor expects some C# (not JS) code. The @ after the = is optional. "() => methodCall()" is Ok but when there are no parameters just "methodCall" is more efficient.

methodCall() should return void or Task here.

Upvotes: 0

Postlagerkarte
Postlagerkarte

Reputation: 7117

If you prefix your on{event} html element with @ Blazor treats the attribute's value as an c# event handler.

If you ommit the @ sign the attribute is treated as a regular html even handler, i.e. it calls a javascript method.

Pay attention if you read through older posts or blogs because in previous versions of Blazor it was valid to write:

<button onclick="@OnClick">

This was confusing and after 3.0 Preview 6 all directives follow a common pattern.

@directive(-suffix(:name))(="value")

The reason given by the Blazor team for the change:

This makes C# event handlers distinct from JS event handlers because all C# event handlers are indicated by attributes prefixed with the @ symbol.

Upvotes: 2

enet
enet

Reputation: 45596

When you place the "@" before the "onclick", you create a compiler directive. This constructs is going to be enforced in the future, if it is not yet enforced. It instructs the compiler to create an EventCallback object, which provide the appropriate delegate for necessary to handle the code you assign as the value of the @onclick directive. This setting: @onclick="() => methodCall()" tells the compiler to produce an EventCallback object that provide the appropriate delegate to execute a lambada expression. Note that you use this construct when you want to pass a value to the method encapsulated by the lambada expression, as for instance:

@onclick="() => methodCall('Hello world')"

void methodCall(string str) { }

If you don't have to pass a value to a called method you should construct the @onclick directive as such: @onclick="methodCall" or @onclick="@methodCall" The "@" sign tells the compiler that the value of the @onclick directive is executable code, and not merely a string, in which case an error would have been triggered. But as you can see, the "@" sign can be omitted, and no error is raised because the compiler knows it is a method name for which it creates an EventCallback struct object with the appropriate delegate.

This onclick="@methodCall()" is wrong. It tells Blazor to create an input Html element whose value should be a JavaScript method named 'methodCall', and it should be defined and executed in Blazor (C#). No such an animal.

You may use construct like this: `onclick="methodCall()", in which case you'll need a JavaSript method named methodCall defined...

You can also do this: onclick="alert('I'm a JavaScript method')"

What is most important to remember that when you use the Html element attribute onclick, its value should be a JavaScript method. This is entriely different than the @onclick compiler directive...

Hope this helps...

Upvotes: 8

Related Questions