Getting ArgumentOutOfRangeException using for loop in Blazor component

依然范特西╮ 提交于 2019-12-11 16:58:36

问题


I'm trying out Blazor and I'm getting this exception when I'm trying to load a list of checkboxes using a for loop.

I've created the list here:

public List<Month> Months { get; set; }

protected override void OnInitialized()
        {
            List<Month> months = new List<Month>()
            {
                new Month{MonthId = 0, MonthName = "All Months", isMonthChecked = false},
                new Month{MonthId = 1, MonthName = "Jan", isMonthChecked = false},
                new Month{MonthId = 2, MonthName = "Feb", isMonthChecked = false},
                new Month{MonthId = 3, MonthName = "Mar", isMonthChecked = false},
                new Month{MonthId = 4, MonthName = "Apr", isMonthChecked = false},
                new Month{MonthId = 5, MonthName = "May", isMonthChecked = false},
                new Month{MonthId = 6, MonthName = "Jun", isMonthChecked = false},
                new Month{MonthId = 7, MonthName = "Jul", isMonthChecked = false},
                new Month{MonthId = 8, MonthName = "Aug", isMonthChecked = false},
                new Month{MonthId = 9, MonthName = "Sep", isMonthChecked = false},
                new Month{MonthId = 10, MonthName = "Oct", isMonthChecked = false},
                new Month{MonthId = 11, MonthName = "Nov", isMonthChecked = false},
                new Month{MonthId = 12, MonthName = "Dec", isMonthChecked = false}
            };
};

            Months = months.ToList();
            base.OnInitialized();

Then, I created the loop in the Blazor component:

@{ 
            for (int i = 0; i < @Months.Count(); i++)
            {
            <ul>
                <li><label for="@Months[i].MonthId" id="checkboxLabel">@Months[i].MonthName</label></li>
                <li><InputCheckbox id="@Months[i].MonthId" @bind-Value="@Months[i].isMonthChecked"></InputCheckbox></li>
            </ul>
            }
        }

I've stepped through the debugger and it is pulling the correct data, but when it finishes, it gives me the error. If I reduce the count to 12 (should be 13), it works. Not sure what is going on here.


回答1:


You can solve it like this:

@for (int j = 0; j < Months.Count; j++)
{
    int i = j;  // a local copy to solve the capture problem

    <ul>
        <li><label for="@Months[i].MonthId" id="checkboxLabel">@Months[i].MonthName</label></li>
        <li><InputCheckbox id="@Months[i].MonthId" @bind-Value="@Months[i].isMonthChecked"></InputCheckbox></li>
    </ul>
}

Which means this is a new, Blazor specific variation on 'capturing the loop variable'.

When you look at the <pagename>.razor.g.cs file you can see that the checkbox requires two lambda's, here is a snippet:

 __value => Months[i].isMonthChecked = __value

and after the for-loop, when the RenderTree is being built, the value of i will be Count for all months.

Using Count()-1 in the original code (your temporary fix) will prevent the exception but note that the form will not function properly, the wrong month will be checked.

General conclusion: don't mix EditForm with a for-loop. foreach() is safe.




回答2:


I prefer to use a foreach statement in this case :

@foreach(var month in _months)
{
    <ul>
        <li><label for="@month.MonthId">@month.MonthName</label></li>
        <li><InputCheckbox id="@month.MonthId" @bind-Value="@month.IsMonthChecked" /></li>
    </ul>
}

@code {
    private IEnumerable<Month> _months;

    protected override void OnInitialized()
    {
        _months = new List<Month>
        {
            new Month{ MonthId = 0, MonthName = "All Months", IsMonthChecked = false },
            new Month{ MonthId = 1, MonthName = "Jan", IsMonthChecked = false },
            new Month{ MonthId = 2, MonthName = "Feb", IsMonthChecked = false },
            new Month{ MonthId = 3, MonthName = "Mar", IsMonthChecked = false },
            new Month{ MonthId = 4, MonthName = "Apr", IsMonthChecked = false },
            new Month{ MonthId = 5, MonthName = "May", IsMonthChecked = false },
            new Month{ MonthId = 6, MonthName = "Jun", IsMonthChecked = false },
            new Month{ MonthId = 7, MonthName = "Jul", IsMonthChecked = false },
            new Month{ MonthId = 8, MonthName = "Aug", IsMonthChecked = false },
            new Month{ MonthId = 9, MonthName = "Sep", IsMonthChecked = false },
            new Month{ MonthId = 10, MonthName = "Oct", IsMonthChecked = false },
            new Month{ MonthId = 11, MonthName = "Nov", IsMonthChecked = false },
            new Month{ MonthId = 12, MonthName = "Dec", IsMonthChecked = false }
        };
        base.OnInitialized();
    }
}


来源:https://stackoverflow.com/questions/58843339/getting-argumentoutofrangeexception-using-for-loop-in-blazor-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!