Добавление вкладки в приложение Blazor server переопределяет источники данных (и имена) со всех предыдущих вкладок

#tabs #blazor

#вкладки #блейзор

Вопрос:

Я все еще новичок в этом, так что извините меня, если есть очевидный ответ.

Я создал интерфейс с вкладками с интересным недостатком. Нажатие на кнопку 1 создает вкладку с правильным именем DxDataGrid и именем вкладки, но при нажатии кнопки 2 вновь созданные вкладка 2 и вкладка 1 отображают данные и имя вкладки, которые применяются к кнопке 2. То же самое происходит, если я нажимаю кнопки в обратном порядке, и то же поведение происходит при последующих нажатиях кнопок.

Это поведение может быть связано: при создании вкладки 1 сетка загружается немедленно, но вы должны щелкнуть каждую вкладку (после создания второй вкладки), чтобы они загрузились.

 lt;DxMenuItem Text="Button 1" Click='() =gt; AddNewTab("Grid1")' /gt; lt;DxMenuItem Text="Button 2" Click='() =gt; AddNewTab("Grid2")' /gt;  lt;DxTabs RenderMode="TabsRenderMode.OnDemand"gt;  @for (int i = 0; i lt; count; i  )  {  @switch (caseStmtTabName[tdiIndex])  {  case "Grid1":  @renderGrid1BrowsePage(tdiIndex)  break;  case "Grid2":  @renderGrid2BrowsePage(tdiIndex)  break;  }  } lt;/DxTabsgt;  @code  int tdiIndex = 0; int count = 0; string[] caseStmtTabName = new string[99];  public void AddNewTab(string tabName) {  tdiIndex  ;  caseStmtTabName[tdiIndex] = tabName;  count  ; }   private RenderFragment renderGrid1BrowsePage(int index) {  RenderFragment grid1Item = grid1TabChildContent =gt;  {  grid1TabChildContent.OpenComponentlt;DxTabPagegt;(0);  grid1TabChildContent.AddAttribute(1, "Text", "Grid1");  grid1TabChildContent.AddAttribute(2, "ActiveTabIndex", index);  grid1TabChildContent.AddAttribute(3, "ChildContent", (RenderFragment)((grid1TabPageChildContent) =gt;  {  grid1TabPageChildContent.OpenComponentlt;Grid1gt;(0);  grid1TabPageChildContent.CloseComponent();  }));  grid1TabChildContent.CloseComponent();  };  //tdiIndex  ;  return grid1Item; }   private RenderFragment renderGrid2BrowsePage(int index) {  RenderFragment grid2Item = grid2TabChildContent =gt;  {  grid2TabChildContent.OpenComponentlt;DxTabPagegt;(0);  grid2TabChildContent.AddAttribute(1, "Text", "Grdi2");  grid2TabChildContent.AddAttribute(2, "ActiveTabIndex", index);  grid2TabChildContent.AddAttribute(3, "ChildContent", (RenderFragment)((grid2TabPageChildContent) =gt;  {  grid2TabPageChildContent.OpenComponentlt;Grid2gt;(0);  grid2TabPageChildContent.CloseComponent();  }));  grid2TabChildContent.CloseComponent();  };  //tdiIndex  ;  return grid2Item; }  

Я понимаю, что переписывание «страниц визуализации» для каждой кнопки является МОКРЫМ, но передача строки в тип данных будет другой задачей на другой день (наряду с несколькими другими вещами выше).

Спасибо за любой ваш совет!

Комментарии:

1. Фрагмент визуализации получает апраметр index , который он никогда не использует.

2. Индекс применяется к ActiveTabIndex.

3. Нет, "index" это не index так . Ваш TabIndex получает строку.

4. Ты прав! Однако удаление кавычек не меняет поведения.

5. После обновления tdiIndex при втором щелчке это вызывает повторную визуализацию. Цикл выполняется, переданное значение tdiIndex будет одинаковым для обеих итераций. Ваш код работает так, как ожидалось.

Ответ №1:

Ваш код ведет себя так, как вы его закодировали.

Нажмите кнопку 1, и вы увеличите tdiIndex значение до 1 и добавите «Grid1» в caseStmtTabName с индексом 1. Вы показываете одну вкладку.

Нажмите на кнопку 2, и вы увеличите tdiIndex значение до 2 и добавите Grid2 в caseStmtTabName с индексом 2.

Теперь посмотрите на свой код цикла:

 @switch (caseStmtTabName[tdiIndex])  

В этот момент tdiIndex равно 2 для обеих итераций цикла и, таким образом caseStmtTabName[tdiIndex] , возвращает «Grid2» и, таким образом,

 case "Grid2":  @renderGrid2BrowsePage(tdiIndex)  break;  

ему звонили оба раза. Именно то, что, как я полагаю, вы видите.

Я не использую DevExpress, поэтому не могу дать точный ответ. Вот общая версия вашего кода с использованием стандартных компонентов Blazor и начальной загрузки, чтобы продемонстрировать методы, которые вы можете использовать.

 @page "/"  lt;div class="m-2 p-2"gt;  lt;button class="btn btn-primary" @onclick="() =gt; AddTab(1)"gt;Add Grid 1lt;/buttongt;  lt;button class="btn btn-dark" @onclick="() =gt; AddTab(2)"gt;Add Grid 2lt;/buttongt;  lt;button class="btn btn-info" @onclick="() =gt; AddTab(3)"gt;Add Grid 3lt;/buttongt; lt;/divgt;  lt;ul class="nav nav-pills"gt;  @foreach (var tab in this.displayTabs)  {  lt;li class="nav-item"gt;  lt;a class="nav-link @this.ActiveTab(tab) hand" aria-current="page" @onclick="() =gt; SetActiveContent(tab)"gt;@tab.Namelt;/agt;  lt;/ligt;  } lt;/ulgt;  @foreach (var tab in this.displayTabs) {  lt;div @key="tab" class="@this.ShowTab(tab)"gt;  @tab.Content  lt;/divgt; } lt;stylegt;  .show-content {  display: block;  }   .hide-content {  display: none;  }   .hand {  cursor: pointer;  } lt;/stylegt;  @code {  class Tab  {  public int Id { get; set; }  public string Name { get; set; } = string.Empty;  public RenderFragment? Content { get; set; }  }   Listlt;Tabgt; tabs = new();   IEnumerablelt;Tabgt; displayTabs =gt; this.tabs.OrderBy(item =gt; item.Id);   int activeTabIndex;   string ActiveTab(Tab tab)  =gt; GetActiveIndex() == tab.Id ? "active" : string.Empty;   string ShowTab(Tab tab)  =gt; GetActiveIndex() == tab.Id ? "show-content" : "hide-content";   void SetActiveContent(Tab tab)  =gt; activeTabIndex = tab.Id;   int GetActiveIndex()  {  if (tabs.Any(item =gt; item.Id == activeTabIndex))  return activeTabIndex;  if (tabs.Count gt; 0)  return tabs[0].Id;  return 0;  }   void AddTab(int index)  {  if (tabs.Any(item =gt; item.Id == index))  {  tabs.Remove(tabs.First(item =gt; item.Id == index));  return;  }  tabs.Add(new Tab()  {  Id = index,  Name = $"Grid {index}",  Content = (builder) =gt;  {  builder.AddMarkupContent(0, $"lt;divgt;Hello {index}lt;/divgt;");  }  });  activeTabIndex = index;  } }