Условные атрибуты, которые не являются булевыми в блазоре - PullRequest
1 голос
/ 30 октября 2019

Я пытаюсь создать свой собственный компонент с системой флажков, чтобы узнать, нужен ли мне атрибут или нет (типа int / float и т. Д.)

<input type="checkbox" @bind="isMinInt" />
@if (isMinInt == true) {
    <input type="number" @bind="MinInt"/>
}

Поэтому я хотел бы заменитьэто @if:

@if(isMinInt == true) {
    <MyComponent @bind-Value="ValueInt" Min="@MinInt"/>
} else {
    <MyComponent @bind-Value="ValueInt"/>
}

чем-то вроде

<MyComponent @bind-Value="ValueInt" 
             @if(isMinInt == true ? Min="@MinInt" : String.Empty />

, потому что у меня будет много атрибутов в моем компоненте, и я хотел бы сделать его проще

РЕДАКТИРОВАТЬ + Решение

Теперь используя @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;
    }
}

РЕДАКТИРОВАТЬ + Решение 2

Теперь используя @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;
    }
}

Причина, по которой я использую Int32.MinValue, заключается в том, что MyComponent соответствует <input type="number">, где его min привязан к моему MinInt, поэтому, если я использую0 вместо Int32.MinValue это не позволит мне перейти на отрицательные числа.

1 Ответ

1 голос
/ 30 октября 2019

У меня будет много атрибутов в моем компоненте, и я хотел бы сделать его проще

Вы не можете сделать это напрямую. Однако в качестве обходного пути вы можете использовать @attributes для динамического связывания атрибутов. Например:

<MyComponent @bind-Value="ValueInt" @attributes="@a_dictionary_expression"  />

Где @a_dictionary_expression - это выражение C # , которое может быть оценено во время выполнения. Более того, вы даже можете создать пользовательскую функцию для расчета словаря:

<MyComponent @bind-Value="ValueInt" @attributes="getAttributes()"  /gt;

@code {
    ... 
    private IDictionary getAttributes()
    {
        var dict = new Dictionary(){};
<strike>        if(isMinInt) {
            dict.Add("Min", $"{MinInt}");
        }</strike>   // this will introduce a bug, see <b>Edit2</b> for more details
        return dict ;
    }
}

[Edit] : вот способ визуализации атрибутов в одной строке

<input @bind-Value="ValueInt" @attributes="@(isMinInt? new Dictionary<string,object>{ Min= @Min} : new Dictionary<string,object>{})" />

[Edit2]

Приведенный выше код будет содержать ошибку, что MyComponent не обновляется правильно. Причина в том, что параметры <MyComponent>, полученные из предыдущего @attributes, не очищаются автоматически при получении нового @attributes.

Например,

  1. первый раз @attributes равен {Min=1}, и это приводит к выражению:
    MyComponent.Min=1;
    
  2. Второй раз @attributes is {}, поскольку внутри него нет атрибута, он не назначит для него параметры, поэтому MyComponent.Min остается прежним.

Чтобы исправить это, измените приведенный выше код, как показано ниже:

private IDictionary<string, object> GetAttributesInt() {
    var dict = new Dictionary<string, object>() { };
    dict["Min"] = this.isMinInt ? MinInt : 0 ;
    return dict;
}
...