Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select component(tags mode) data source is not correct #1912

Closed
LiuyangRY opened this issue Sep 3, 2021 · 11 comments
Closed

Select component(tags mode) data source is not correct #1912

LiuyangRY opened this issue Sep 3, 2021 · 11 comments

Comments

@LiuyangRY
Copy link

Describe the bug

I use the select component(tags mode), changing the data source of the select component according to a selected value. While the data source is not showed correctly as I wanted, I watched the value but didn't find the reason,.

Steps to reproduce (please include code)

QueryCondition
Here is the code:
Select component setup:
<Select Mode="tags" EnableSearch="true" MaxTagCount="5" TItem="string" TItemValue="string" @bind-Values="@context.Area" AllowClear="true"> <SelectOptions> @if (AreaList?.Any() ?? false) { @foreach (AreaDTO area in AreaList) { <SelectOption TItemValue="string" TItem="string" Value=@area.AreaID Label=@area.AreaID /> } } </SelectOptions>
Data source changed:
private void JobTypeChanged(NameValueRecord<string, string> item) { switch (item.Value) { case "RT": AreaList = RTAreaList; isRT = true; break; case "NonRT": AreaList = NonRTAreaList; isRT = false; break; default: break; } JobSetupService.QueryModel.area = string.Join(",", AreaList.Select(a => a.AreaID)); StateHasChanged(); }

@LiuyangRY
Copy link
Author

I am sorry for the code format, it is my first copying code.

@anranruye
Copy link
Member

anranruye commented Sep 3, 2021

@LiuyangRY thanks for contacting us.

When you use a foreach or for loop, you should add @key attribute to the component in the loop.

However, I'm not sure this can solve your issue. I recommend you to use the DataSource approach of Select component. For your use-case, you can just use a string collection.

You can post your code surrounded by ```

@anddrzejb
Copy link
Member

@LiuyangRY Can you post a minimal repro?

@LiuyangRY
Copy link
Author

@anranruye @anddrzejb Thanks for your suggestions, I have added the @key attribute, but it does not solve the problem. I will post the code so that you can track the problem easily.
Test.razor :

@page "/test"

<div class="queryDiv">
    <Select Mode="default"
            DataSource="@jobTypeList"
            @bind-Value="@jobType"
            LabelName="@nameof(NameValueRecord<string, string>.Name)"
            ValueName="@nameof(NameValueRecord<string, string>.Value)"
            DefaultActiveFirstOption="true"
            OnSelectedItemChanged="JobTypeChanged">
    </Select>
    <Select Mode="tags"
            EnableSearch="true"
            MaxTagCount="5"
            TItem="string"
            TItemValue="string"
            @bind-Values="@queryModel.Area"
            AllowClear="true">
        <SelectOptions>
            @if (AreaList?.Any() ?? false)
            {
                @foreach (TestNameSpace.AreaDTO area in AreaList)
                {
                    <SelectOption @key="@area.ObjectID" TItemValue="string" TItem="string" Value="@area.AreaID" Label="@area.AreaID" />
                }
            }
        </SelectOptions>
    </Select>
</div>

Test.razor.cs:

using Model.Record;
using System.Collections.Generic;
using System.Linq;
using TestNameSpace;

namespace Client.Pages
{
    public partial class Test
    {
        #region Field
        private string jobType = "List1";
        #endregion

        #region Properity
        private List<AreaDTO> RTAreaList { get; set; } = new();

        private List<AreaDTO> NonRTAreaList { get; set; } = new();

        readonly QueryModel queryModel = new();

        private static readonly List<NameValueRecord<string, string>> jobTypeList = new()
        {
            new NameValueRecord<string, string>("List1", "List1"),
            new NameValueRecord<string, string>("List2", "List2")
        };
        #endregion

        #region DataSource
        private List<AreaDTO> AreaList { get; set; } = new();
        #endregion
        protected override void OnInitialized()
        {
            InitAreaInfo();
        }

        private void InitAreaInfo()
        {
            for (int i = 0; i < 7; i++)
            {
                RTAreaList.Add(new AreaDTO { ObjectID = i, AreaID = i.ToString() });
            }
            for (int i = 7; i < 10; i++)
            {
                NonRTAreaList.Add(new AreaDTO { ObjectID = i, AreaID = i.ToString() });
            }
            AreaList = RTAreaList;
        }

        private void JobTypeChanged(NameValueRecord<string, string> item)
        {
            switch (item.Value)
            {
                case "List1":
                    AreaList = RTAreaList;
                    break;
                case "List2":
                    AreaList = NonRTAreaList;
                    break;
                default:
                    break;
            }
            queryModel.area = string.Join(",", AreaList.Select(a => a.AreaID));
            StateHasChanged();
        }
    }
    
}

namespace TestNameSpace
{
    public class AreaDTO
    {
        /// <summary>
        /// AREA_ID
        /// </summary>
        public string AreaID { get; set; }

        /// <summary>
        /// OBJECT_ID
        /// </summary>
        public long ObjectID { get; set; }
    }

    public class QueryModel
    {
        public IEnumerable<string> Area
        {
            get => string.IsNullOrWhiteSpace(area) ? null : area?.Split(",");
            set => area = value is null ? null : string.Join(",", value.Where(v => !string.IsNullOrWhiteSpace(v)));
        }
        #region Field
        public string area;
        #endregion
    }
}

@anranruye
Copy link
Member

@LiuyangRY confirmed this is a bug.
use

...
    private async void JobTypeChanged(NameValueRecord item)
    {
        switch (item.Value)
        {
            case "List1":
                AreaList = RTAreaList;
                break;
            case "List2":
                AreaList = NonRTAreaList;
                break;
            default:
                break;
        }

        queryModel.area = null;

        await Task.Delay(1);
        queryModel.area = string.Join(",", AreaList.Select(a => a.AreaID));
        StateHasChanged();
    }
...
    public class QueryModel
    {
        public IEnumerable<string> Area
        {
            get => string.IsNullOrWhiteSpace(area) ? Array.Empty<string>() : area?.Split(",");
            set => area = value is null ? null : string.Join(",", value.Where(v => !string.IsNullOrWhiteSpace(v)));
        }
        #region Field
        public string area;
        #endregion
    }
...

to workaround.

@LiuyangRY
Copy link
Author

@anranruye I attempted this solution and I found the highlight of selected items disappeared.

@anranruye
Copy link
Member

@LiuyangRY do you change null in get => string.IsNullOrWhiteSpace(area) ? null : area?.Split(","); to Array.Empty<string>() ?

@LiuyangRY
Copy link
Author

@anranruye Sorry, it's my inattention. Now it works normally. I want to know is this will be fixed one day so that I can avoid using Task.Delay(1) in my code?

@anranruye
Copy link
Member

@anddrzejb this one is similar to #1536 and #1719, we only solved the situations for single value(default mode), but not for multiple values.

@LiuyangRY Of course we will, but now we don't have a plan. Welcome to open a pr if you are interested in this issue.

@LiuyangRY
Copy link
Author

@anranruye I am busy on rebuilding the company's project, what I can do is just report some issues during process. I am glad to contribute to ant-design-blazor one day.
Thanks for your help and contribution.

@anddrzejb
Copy link
Member

anddrzejb commented Sep 6, 2021

@anranruye I tested the #1536 for the multiple (and also written a bUnit test for that scenario) and it works as it should.
I just made a modification to my #1719 issue recreation so it also contains a scenario for multiple and it also works correctly.
It does seem to work in a weird way when Mod=tags. I haven't yet had time to analyze @LiuyangRY code to investigate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants