Один пользовательский элемент управления обновляет другой во время обратной передачи AJAX? - PullRequest
1 голос
/ 17 апреля 2009

Я разработал пользовательский элемент управления, который отображает список продуктов, и он работает довольно хорошо. Затем я поместил этот пользовательский элемент управления в другой пользовательский элемент управления, который позволяет пользователю выбирать другие критерии и обновления UC продукта, чтобы показать эти продукты, все довольно гладко и с AJAX через UpdatePanel.

Все работало просто отлично ... потом пришло другое требование. Элемент управления "поиск" должен быть отделен от элемента управления продукта (чтобы их можно было позиционировать отдельно). Сначала я думал, что это не проблема, поскольку я предоставляю элементу управления поиском ссылку на элемент управления продуктом, а затем он обращается к нему по ссылке, а не непосредственно внутри элемента управления (который был удален).

И они разговаривают. Но продукт управления загружается, но отображать отказывается.

Я проверил, и он передается по ссылке, а не по копии (насколько я могу судить).

В элементе управления поиском есть панель обновления. В контроле продукта есть панель обновлений. И, кроме того, для правильной оценки есть страница обновлений, окружающая их обоих на реальной странице поиска aspx.

Я попытался установить условную панель обновления элемента управления продуктом, а затем вручную запустить метод .Update ().

В чем секрет?

ТИА!

решаемые

Спасибо Jamie Ide за подсказку по использованию событий.

Поисковый контроль и Контроль продукта по-прежнему имеют внутренние панели обновлений, и НИКАКИЕ БОЛЬШЕ их не имеют на этой конкретной странице.

Поисковый элемент управления теперь вызывает событие OnSearchResultsUpdated и выставляет найденные элементы в свойствах. Страница подписывается на это событие, получает свойства и передает их элементу управления продукта, а также запускает метод .Refresh () в элементе управления продукта, который просто вызывает .Update () на своей внутренней панели обновления.

Контроль продукта, к вашему сведению, принимает продукты в нескольких вариантах. Список отдельных SKU, список идентификаторов продуктов, именованная коллекция в нашей базе данных и, наконец, данная категория продуктов.

Наши дизайнеры должны иметь возможность создать новую страницу, перетащить на нее элемент управления, установить некоторые свойства и вуаля! Новая страница сайта. Они не хотят требовать участия программиста. Таким образом, сохранение контроля является обязательным требованием. К счастью, все внесенные мной изменения полностью работают с другими элементами управления продуктом.

БОЛЬШОЕ СПАСИБО!

Ответы [ 4 ]

2 голосов
/ 17 апреля 2009

Не думаю, что здесь действительно достаточно информации для работы, но я думаю, что элемент управления Product не привязывается к данным. Вы можете попробовать вызвать myProdcutsCtrl.DataBind () из элемента управления поиском (или что-то внутри элемента управления Product, которое вызывает DataBind (), например, myProductCtrl.Search (value1, value2, value3).

Еще одна вещь, которую вы можете попробовать, это удалить UpdatePanels и посмотреть, все ли работает. Затем добавьте их обратно, как только вы включите основные функции.

ОБНОВЛЕНИЕ: Я пошел вперед и добавил пример кода, который работает здесь, который, я считаю, выполняет то, что вы хотите. Ниже приведены фрагменты для экономии места, но они включают весь код, необходимый для его запуска. Надеюсь, это, по крайней мере, даст вам кое-что для справки.

Что попробовать:

  1. EnablePartialRendering = "true | false", установив его в false, заставит естественные обратные передачи и хорошо для отладки проблем UpdatePanel.
  2. Убедитесь, что вы видите Идет загрузка ... появляется на вашем экране. (может быть, слишком быстро в зависимости от вашего компьютера разработчика)

Page.aspx

<%@ Register Src="~/Product.ascx" TagPrefix="uc" TagName="Product" %>
<%@ Register Src="~/Search.ascx" TagPrefix="uc" TagName="Search" %>

...

<asp:ScriptManager runat="server" ID="sm" EnablePartialRendering="true" />
Loaded <asp:Label ID="Label1" runat="server"><%= DateTime.Now %></asp:Label>

<asp:UpdateProgress runat="server" ID="progress" DynamicLayout="true">
<ProgressTemplate><b>Loading...</b></ProgressTemplate>
</asp:UpdateProgress>

<uc:Search runat="server" ID="search" ProdcutControlId="product" />
<uc:Product runat="server" ID="product" />

Search.ascx

<asp:UpdatePanel runat="server" ID="searchUpdate" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<p>
    <asp:Label runat="server" AssociatedControlID="filter">Less than</asp:Label>
    <asp:TextBox runat="server" ID="filter" MaxLength="3" />
    <asp:Button runat="server" ID="search" Text="Search" OnClick="SearchClick" />
</p>
</ContentTemplate>
</asp:UpdatePanel>

Search.ascx.cs

    public string ProdcutControlId { get; set; }
    protected void SearchClick(object sender, EventArgs e)
    {
        Product c = this.NamingContainer.FindControl(ProdcutControlId) as Product;
        if (c != null)
        {
            c.Search(filter.Text);
        }

    }

Product.ascx

<asp:UpdatePanel runat="server" ID="productUpdate" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
<asp:Label runat="server">Request at <%= DateTime.Now %></asp:Label>
<asp:ListView runat="server" ID="product">
<LayoutTemplate>
    <ul>
        <li id="itemPlaceHolder" runat="server" />
    </ul></LayoutTemplate>
<ItemTemplate>
    <li><%# Container.DataItem %></li></ItemTemplate>
</asp:ListView>

</ContentTemplate>
</asp:UpdatePanel>

Product.ascx.cs

IEnumerable<int> values = Enumerable.Range(0, 25);
public void Search(string val)
{
    int limit;
    if (int.TryParse(val, out limit))
        product.DataSource = values.Where(i => i < limit);
    else
        product.DataSource = values;
    product.DataBind();
    productUpdate.Update();
}

Код НЕ представляет лучшие практики, это просто пример!

1 голос
/ 17 апреля 2009

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

Я делаю нечто подобное с двумя пользовательскими элементами управления для отображения основных данных. Мастер генерирует событие, когда элемент выбирается из списка, содержащая страница обрабатывает событие и вызывает метод отображения подробностей для отображения выбранного элемента. Если я правильно помню, у моей первой попытки были элементы управления UpdatePanels в пользовательских элементах управления, и я не смог заставить это работать. Наличие пользовательских элементов управления внутри UpdatePanel на странице работает нормально.

1 голос
/ 17 апреля 2009

По умолчанию, если обратная передача выполняется из UpdatePanel, только этот элемент управления будет обновляться / повторно отображаться (это называется частичным отображением страницы).

Чтобы также обновить / перерисовать другие UpdatePanels, вам необходимо:

  • установить для свойства UpdateMode значение Always
  • добавить элемент управления, выполняющий обратную передачу, в их коллекцию триггеров

Проверьте эту страницу в MSDN для деталей.

1 голос
/ 17 апреля 2009

Если я правильно вас понял, у вас есть такой макет:

Outer UpdatePanel
  SearchControl
    Search UpdatePanel
  ProductControl
    Product UpdatePanel
      Databound Control

Какая из этих панелей обновлений на самом деле вызывается?

Я предполагаю, что если вы проверяете сетевой трафик с помощью чего-то вроде Fiddler или Firebug , если вы используете Firefox, вы не увидите никакого HTML-кода для появившейся панели обновления продукта назад

Вы пытались сделать что-то вроде:

UpdatePanel productUpdate = 
              Page.FindControl("Product UpdatePanel") as UpdatePanel;

if (null != productUpdate){
  productUpdate.Update();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...