Reputation: 730
I am trying to generate my own component with checkbox system to know if I need the attribute or not (of type int
/ float
etc)
<input type="checkbox" @bind="isMinInt" />
@if (isMinInt == true) {
<input type="number" @bind="MinInt"/>
}
So I would like to replace this @if
:
@if(isMinInt == true) {
<MyComponent @bind-Value="ValueInt" Min="@MinInt"/>
} else {
<MyComponent @bind-Value="ValueInt"/>
}
by something like
<MyComponent @bind-Value="ValueInt"
@if(isMinInt == true ? Min="@MinInt" : String.Empty />
because I will have many attributes on my component and I would like to make it simplier
EDIT + Solution
Now using the @attributes
:
<input type="checkbox" @bind="isMinInt" />
@if (isMinInt == true) {
<input type="number" @bind="MinInt" />
}
<MyComponent @bind-Value="ValueInt" @attributes="GetAttributesInt()" />
@code {
private bool isMinInt = false;
private int MinInt;
private IDictionary<string, object> GetAttributesInt() {
var dict = new Dictionary<string, object>() { };
if (isMinInt)
dict.Add("Min", MinInt);
return dict;
}
}
EDIT + Solution 2
Now using the @attributes
:
<input type="checkbox" @bind="isMinInt" />
@if (isMinInt == true) {
<input type="number" @bind="MinInt" />
}
<MyComponent @bind-Value="ValueInt" @attributes="GetAttributesInt()" />
@code {
private bool isMinInt = false;
private int MinInt;
private IDictionary<string, object> GetAttributesInt() {
var dict = new Dictionary<string, object>() { };
dict["Min"] = this.isMinInt ? MinInt : Int32.MinValue;
return dict;
}
}
The reason why I'm using Int32.MinValue
it's because MyComponent
correspond to an <input type="number">
where his min
is bind to my MinInt
, so if I use 0
in the place of Int32.MinValue
it won't allow me to go for negative numbers.
Upvotes: 5
Views: 4364
Reputation: 528
I used this simple solution and it work, hope this help you too:
<input id="@InputId" aria-labelledby="@(!string.IsNullOrWhiteSpace(InputId) ? "this is test" : null)">
Upvotes: 2
Reputation: 25350
I will have many attributes on my component and I would like to make it simplier
You can't do that directly. However, as a walkaround, you can use the @attributes
to bind attributes dynamically. For example:
<MyComponent @bind-Value="ValueInt" @attributes="@a_dictionary_expression" />
Where @a_dictionary_expression
is a C# expression that can be evaluated at runtime. What's more, you can even create a custom function to calculate the dictionary:
<MyComponent @bind-Value="ValueInt" @attributes="getAttributes()" /gt; @code { ... private IDictionary getAttributes() { var dict = new Dictionary(){};if(isMinInt) { dict.Add("Min", $"{MinInt}"); }// this will introduce a bug, see Edit2 for more details return dict ; } }
[Edit]: Here's a way to render the attributes within a single line
<input @bind-Value="ValueInt" @attributes="@(isMinInt? new Dictionary<string,object>{ Min= @Min} : new Dictionary<string,object>{})" />
[Edit2]
The above code will introduce a bug that the MyComponent
is not updated correctly. The reason is the parameters of <MyComponent>
received from previous @attributes
is not automatically cleared when a new @attributes
received.
For example,
@attributes
is {Min=1}
, and it results in a statement:
MyComponent.Min=1;
@attributes
is {}
, because there's no attribute inside it, it won't assign parameters for it, thus the MyComponent.Min
remains the same.To fix that, change the above code as below:
private IDictionary<string, object> GetAttributesInt() {
var dict = new Dictionary<string, object>() { };
dict["Min"] = this.isMinInt ? MinInt : 0 ;
return dict;
}
Upvotes: 2