Могу ли я использовать петли в повторителе? Это рекомендуется? - PullRequest
1 голос
/ 30 марта 2010

В моем источнике данных есть Rating dataItem, содержащий целое число от 0 до 5. Я хочу печатать звезды по назначению.

Я пытаюсь сделать это в пределах Repeater контроля:

<b>Rating:</b>

<% for (int j = 1; j <= DataBinder.Eval(Container.DataItem, "Rating"); j++)
{  %>
<img src="App_Pics/fullstar.png" />
<% }
for (int j = 1; j <= 5 - DataBinder.Eval(Container.DataItem, "Rating"); j++)
{ %>
<img src="App_Pics/emptystar.png" />
<%} %>
  1. Я получаю ошибку The name 'Container' does not exist in the current context. Это странно, потому что когда я использовал <%# DataBinder.Eval(Container.DataItem, "Name")%> строку раньше, она работала отлично.
  2. Разумно ли включать циклы в мою страницу aspx? Я думаю, что это не очень удобно. Какие у меня альтернативы?
  3. Что это значит #?

Большое спасибо.

Ответы [ 6 ]

5 голосов
/ 30 марта 2010

# указывает код, который должен быть выполнен, когда привязка данных происходит (т.е. когда DataBind() вызывается для элемента управления или страницы). Синтаксис <%# %> является эквивалентом привязки данных <%= %>, поэтому, к сожалению, вы не можете просто обернуть свой цикл в блоки <%# %> и покончить с этим.

Вы можете обойти это ограничение, внедрив метод code-behind и передав рейтинг методу:

<%# GetStars(Convert.ToInt32(DataBinder.Eval(Container.DataItem, "Rating"))) %>

А затем реализовать метод как:

protected string GetStars(int rating)
{
    string output = string.Empty;
    for (int j = 1; j <= rating; j++) output += "<img src=\"App_Pics/fullstar.png\" />";
    for (int j = 1; j <= 5 - rating; j++) output += "<img src=\"App_Pics/emptystar.png\" />";
    return output;
}
2 голосов
/ 30 марта 2010

# указывает на элемент с привязкой к данным, поэтому вы видите ошибку, о которой упоминали; вы используете DataBinding вне контекста.

Лучшим решением было бы преобразовать ваш звездный рейтинг во внешнее управление (управление ascx). Вы можете добавить свойство с именем «Rating», назначить его из контекста, связанного с данными, и выполнить цикл в элементе управления star rater.

1 голос
/ 30 марта 2010

Я бы не рекомендовал использовать цикл таким образом. Конечно, есть способы соединить 5 изображений так, как вам нужно, с включенными или выключенными звездами, но другая идея состоит в том, чтобы просто создать 6 статических изображений с включенными от 0 до 5 звездами. 0star.jpg, 1star.jpg и т. Д. Тогда ваше значение «rating» можно использовать просто для генерации соответствующего имени файла.

1 голос
/ 30 марта 2010

Пункт 2, вы, безусловно, можете это сделать, и вы найдете несколько примеров этого в учебниках и прочем. Лично мне нравится стараться хранить как можно больше кода в коде, но иногда это того не стоит ...

0 голосов
/ 30 марта 2010

Лучшее для меня было бы иметь что-то вроде:

код:

protected List<int> Stars = new List<int> { 1, 2, 3, 4, 5 };
protected int RankingStars = 3;

aspx:

<asp:Repeater runat=server ID=C_Rep_StarsFull DataSource=Stars >
    <ItemTemplate>
          <img src="App_Pics/fullstar.png" runat=server 
                visible=<%# RankingStars >= (int)Container.DataItem %>/>
    </ItemTemplate>
</asp:Repeater>
<asp:Repeater runat=server ID=C_Rep_StarsEmpty DataSource=Stars >
    <ItemTemplate>
          <img  src="App_Pics/emptystar.png" runat=server 
                visible=<%# RankingStars < (int)Container.DataItem %>/>
    </ItemTemplate>
</asp:Repeater>
0 голосов
/ 30 марта 2010

Я не уверен, что циклы - это отличная идея с Repeater контролем. Лучшей практикой является зацикливание самого DataSource (в выделенном фрагменте кода), поэтому для Repeater требуется только одна итерация для визуализации HTML.

Если вам нужна какая-то составная HTML-структура для отображения, я бы выбрал решение jvenema и использовал другой UserControl для ее рендеринга.

...