2

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?

mko
  • 6,638
  • 12
  • 67
  • 118
  • `onclick="@methodCall()"` will only work when methodCall returns JavaScript code. And methodCall() will run on every statechange, not when you click the Btn. – H H Nov 09 '19 at 10:53
  • You probably meant `@onclick="methodCall"`. Check your code before posting. – H H Nov 09 '19 at 10:55
  • Henk Holterman, onclick="@methodCall()" will lead to an error. It won't run at all. Please read my answer to learn the mechanism of this. – enet Nov 09 '19 at 11:38
  • Henk Holterman, care to explain what you mean by "And methodCall() will run on every statechange, not when you click the Btn." – enet Nov 09 '19 at 11:41
  • Make `methodCall()` return `"alert()"`, that will show up. – H H Nov 09 '19 at 12:06

2 Answers2

5

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...

enet
  • 41,195
  • 5
  • 76
  • 113
2

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.

Postlagerkarte
  • 6,600
  • 5
  • 33
  • 52