_
@functions {
string uiLocation =""
protected async void LoadForms()
{
// does an async call relying on the value of uiLocation variable
}
}
Yes, bind is currently always a two-way bind. If you want a more custom scenario, change LoadForms() to also set uiLocation to the new value, and also amend the <option> tags to get the current value, like so:
<option value="A" selected="@(uiLocation == "A")">A_</option>
Appreciate the hint but haven't figured this out yet. How would I access the uiLocation if I can't bind it to the select html control? Seems like a chicken/egg scenario if you can't bind a value and call an event trigger on the same element. I find this to be rather limiting, but i assume I am just missing something.
If I can't have bind and have an onchange for a single dropdown then I need to figure out a way to call an event and reference the selected value of a dropdown within that event. Similar to old school asp webforms where the controls were server side. I haven't seen this ability yet but admittedly I'm still learning it.
Looking at your suggestion again, it looks like if I set the value of uiLocation, it would then set the selected value of the dropdown without me needing the bind keyword. Clever.
My scenario is the opposite though. I want to read the value of the select, and use it for a parameter in a event fired by the onchange of the select element. I can't figure out how to read the value if it isn't bound and not resulting to some javascript interop. If we are forced to go to javascript / interop, than this project loses some of its steam IMO.
You don't need JS interop for this, but you _do_ need to store uiLocation yourself.
The way I approached this (well, in my case, it was for radio buttons, not a drop-down, but same difference) was to create a component EnumRadioButtons that gets passed an enum type as a parameter. That way, it can populate the <option> tags itself using Enum.GetValues(), while holding the selected value as a .NET property.
There's no JS involved it (though there might be if I would use, say, visual effects from a JS library), but there's a fair bit of C# boilerplate involved still.
We are still evolving the "bind" APIs, so over time this might change depending on what people report, but right now there's a better way of achieving your goal.
Instead of using onchange and bind separately, just use bind on its own and then put logic into your property setter to take some action when it changes. This is much clearer than using bind and onchange together because it lets you be totally explicit about what order you want things to run in (e.g., whether you run your logic before the property value is updated, or after that).
This doesn't require resorting to any JS interop.
Example:
<select id="cboLocations" bind="@uiLocation">...</select>
@functions {
string _uiLocation;
string uiLocation
{
get => _uiLocation;
set
{
// Run some logic before the value is updated here...
_uiLocation = value;
// ... or after value is updated here.
}
}
}
I made a workaround for this by creating a method that sets the value of the inputModel:
<input type="number" onchange=@((arg) => OnChange(arg, this.InputModel, inputModel => input.Number) />
@functions
{
void OnChange<TObject, TValue>(UIChangeEventArgs uIChangeEventArgs, TObject target, Expression<Func<TObject, TValue>> propertyGetter)
{
if (uIChangeEventArgs?.Value != null)
{
var expression = (MemberExpression)propertyGetter.Body;
var property = (PropertyInfo)expression.Member;
property.SetValue(target, uIChangeEventArgs.Value);
// Do your own stuff here
}
}
}
I made a workaround for this by creating a method that sets the value of the inputModel:
<input type="number" onchange=@((arg) => OnChange(arg, this.InputModel, inputModel => input.Number) /> @functions { void OnChange<TObject, TValue>(UIChangeEventArgs uIChangeEventArgs, TObject target, Expression<Func<TObject, TValue>> propertyGetter) { if (uIChangeEventArgs?.Value != null) { var expression = (MemberExpression)propertyGetter.Body; var property = (PropertyInfo)expression.Member; property.SetValue(target, uIChangeEventArgs.Value); // Do your own stuff here } } }Seems like a function what I am needing... care to elaborate what packages/addons needed to be used for getting those params? If i try to use this i am getting something like that: The type or namespace name 'TValue' could not be found (are you missing a using directive or an assembly reference?)
Most helpful comment
We are still evolving the "bind" APIs, so over time this might change depending on what people report, but right now there's a better way of achieving your goal.
Instead of using
onchangeandbindseparately, just usebindon its own and then put logic into your property setter to take some action when it changes. This is much clearer than usingbindandonchangetogether because it lets you be totally explicit about what order you want things to run in (e.g., whether you run your logic before the property value is updated, or after that).This doesn't require resorting to any JS interop.
Example: