Советы по созданию динамического элемента управления «Расширенный поиск» в ASP.NET

StackOverflow https://stackoverflow.com/questions/1406134

Вопрос

альтернативный текст http://img3.imageshack.us/img3/1488/advancedsearch.png

Я создаю интерфейс «Расширенного поиска» в приложении ASP.NET.Мне не нужен SO, чтобы написать это за меня, но я застрял в конкретной проблеме, связанной с динамическими элементами управления и ViewState.Мне хотелось бы получить какое-то направление, как к этому подойти.Вот моя ситуация:

Ингредиенты:

  • Обслуживаемый набор объектов API, представляющих сущности, поля и поиск, который управляет созданием поиска, генерацией SQL и возвратом результатов.Так что обо всем позаботились.
  • АСП.НЕТ 3.5

Желаемая функциональность интерфейса:

(1) При начальной загрузке страницы интерфейс получает предварительно настроенный объект Search с набором объектов SearchCriterion.Он связывает их в набор элементов управления (см. изображение выше).

  • Некоторые элементы поиска проще, например:

    Поле (DropdownList) | Оператор (DropdownList) | Значение (Textbox)

  • Элементы управления критериями поиска для некоторых типов полей содержат важную информацию, хранящуюся в состоянии просмотра, например:

    Поле (DropdownList) | Оператор (DropdownList) | Значение (DropdownList), где распаданный список «значение» заполняется запросом базы данных.

  • Некоторые поля являются поиском других сущностей, что вызывает цепочку селекторов полей, например:

    Field (DropdownList) Поле (DropdownList) | Оператор (DropdownList) | Ценить

(2) Пользователь изменяет поиск:

  • Добавление и удаление критериев поиска нажатием соответствующих кнопок
  • Настройка существующих критериев путем изменения поля, оператора или значения.Изменения в поле или операторе потребуют перенастройки элемента управления путем изменения доступных операторов, изменения элемента управления вводом «Значение» на другой тип или добавления/удаления DropDownLists из раздела «Поля», если поля типа поиска выбраны или не выбраны. .

(3) Наконец, пользователь нажимает «Поиск», чтобы увидеть результаты.

Проблема:

Как вы, вероятно, уже знаете, если отвечаете на этот вопрос, элементы управления, динамически добавленные на страницу, исчезают при обратной передаче.Я создал UserControl, который манипулирует коллекцией элементов управления и аккуратно выполняет шаг (1), описанный выше, как вы можете видеть на прикрепленном изображении.(Очевидно, меня сейчас не волнует стиль.)

Однако в Postback все элементы управления исчезли, и мой объект API поиска исчез.Если бы я мог заставить динамически сгенерированную коллекцию элементов управления работать нормально и оставаться в ViewState, я мог бы проверять элементы управления при обратной передаче, перестраивать объект поиска, а затем аккуратно обрабатывать события управления.

Возможные решения

  • Я мог бы сделать объект поиска сериализуемым и сохранить его в состоянии просмотра.Затем при загрузке страницы я мог бы захватить его и восстановить коллекцию элементов управления во время загрузки страницы.Однако я не уверен, что это будет хорошо сочетаться с событиями, вызывающими элементы управления, и что происходит с состоянием просмотра раскрывающихся списков, содержащих данные из базы данных - могу ли я получить их обратно?Мне крайне нежелательно повторно запрашивать базу данных при каждой обратной передаче.

  • Я мог бы разработать собственный серверный элемент управления (см. эту ссылку) для такого рода вещей...но для меня это новая тема, и она потребует некоторого обучения, плюс я не совсем уверен, будет ли пользовательский серверный элемент управления работать лучше с нефиксированными коллекциями элементов управления.Кто-нибудь знает об этом?

  • Я думал, что смогу добиться этого, используя элементы управления с привязкой к данным - например, я мог бы привязать свою коллекцию критериев к повторителю, который имеет фиксированную коллекцию элементов управления (возможно, скрыть неиспользуемые элементы управления «значение», использовать внутренний повторитель для раскрывающиеся списки «Поля»).Тогда вся информация останется во ViewState...верно?

  • Любые новые идеи будут с благодарностью приняты.

Спасибо за вашу помощь.б.Фанданго

Это было полезно?

Решение

Я программировал около дня, и у меня это прекрасно работало, используя третий вариант, который я предложил в своем вопросе, — элементы управления с привязкой к данным старой школы.На самом деле я подумал об этой идее только тогда, когда меня заставили подробно расписать вопрос - разве с вами это не случается постоянно?

Я поместил свой SearchCriterionControl в asp:Repeater и привязал его к своей коллекции объектов.Для выбора поля я поместил asp:DropDownList внутри вложенного asp:Repeater и привязал к нему массив полей.Все работает прекрасно, сохраняет состояние, на самом деле требуется очень мало кода.Так что, слава богу, мне никогда не приходилось динамически добавлять элементы управления на страницу.

Спасибо за ваши предложения, Эндер, Мэтт и Эндрю Винн.

Другие советы

Поскольку никто больше не пытался этим заняться в течение двух часов, я брошу свою шляпу на ринг с решением, которое вообще не зависит от состояния представления (или модели обратных передач ASP.NET).

Что, если вы захватили все входные значения с помощью jQuery и вместо выполнения обратной передачи отправили сообщение на страницу (или новую страницу results.aspx)?Или вы могли бы сделать все это асинхронным и выполнить Ajax-запрос к веб-методу, получить результаты и заполнить их на стороне клиента по мере необходимости?

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

Читать здесь для получения дополнительной информации об использовании jQuery для доступа к методу страницы ASP.NET.Помните: методы страницы должны быть статическими (это легко упустить).

Я не уверен, что вы делаете на стороне сервера для построения запроса, но я бы высоко рекомендую Линк.Ранее я использовал аналогичную функцию «расширенного поиска» и после нескольких различных попыток обнаружил, что LINQ является прекрасным инструментом для решения этой проблемы, независимо от того, обращаюсь ли я к SQL с помощью LINQtoSQL или просто обращаюсь к коллекции объектов в памяти.

Это сработало очень хорошо, потому что 1) LINQ — это отложенное выполнение и 2) запрос LINQ возвращает другой запрашиваемый объект.Подразумевается, что вы можете связывать свои запросы LINQ вместе по мере их создания на основе входных данных, вместо того, чтобы выполнять один массивный перевод предложений в SQL или любое другое резервное хранилище, которое вы используете (одной из моих попыток было создание предложений SQL со строками, но по-прежнему передавал входные данные через SQLParameters для защиты от SQL-инъекций - это было грязно и сложно, когда созданный вручную LINQ был на порядки проще для понимания и реализации).

Например:

List<string> data; // or perhaps your a DB Context for LINQtoSQL?

var query = data.Where(item => item.contains("foo"));

if( {user supplies length search option} )
    query = query.Where(item => item.Length < 5);

// etc, etc.

// LINQ doesn't do anything until the query is iterated, at which point
// it will construct the SQL statement without you worrying about details or parameter binding
foreach(string value in query)
    ; // do something with the results

Благодаря отложенному выполнению и запрашиваемому типу возвращаемого значения вы можете объединять запросы LINQ с этим выражением в течение всего дня и позволить ему беспокоиться о деталях реализации (например, о преобразовании в запрос SQL) во время выполнения.

Я не могу предоставить вам точные инструкции, которые вам нужно будет выполнить, но НАСТОЯТЕЛЬНО предлагаю изучить жизненный цикл страницы asp.net.Однажды я создал пользовательский элемент управления как DLL.Мне приходилось собирать данные обратной передачи на определенных этапах жизненного цикла, а затем воссоздавать и повторно привязывать данные на других этапах.Кроме того, такие мысли, как состояние просмотра, доступны только в определенные моменты.Я знаю, что мне пришлось переопределить On_init, On_prerender и некоторые другие методы.

Извините, я ничем не могу помочь, но у меня нет с собой кода (он у старого работодателя).Надеюсь, это поможет.

Если вы добавляете элементы управления в дерево элементов управления динамически, вам также необходимо добавить их в постпак.Просто вызовите метод, который создает элемент управления на Page_Load или Page_Init, и элементы управления должны оставаться на странице при обратной передаче.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top