2009-07-10 3 views
2

Я работаю с сторонней системой для реализации некоторых форм на веб-сайте.Правильный шаблон для передачи данных дочерним элементам управления в серверном элементе управления

Сторонняя система предоставляет мне определения XML для этих форм. , например.

<form> 
    <segment> 
     <label>The header</label> 
     <fields> 
      ... 
      <field> 
       <id>field_Dob</id> 
       <type>Date</type> 
       <label>Date of Birth</label> 
       <required>1</required> 
      </field> 
      ... 
     </fields> 
    </segment> 
    ... 
</form> 

Я разбираю этот XML в серверном управлении и программно генерирует дерево элементов управления. Метки элементов управления передаются в XML.

Это часть нашего предложения «ввести» небольшие тексты справки в эту форму.

В идеале я хотел бы передать эти тексты справки из разметки верхнего уровня управления, чтобы не-разработчики (HTML monkies) могли изменять тексты справки и связывать их с полем по его идентификатору. Что-то вроде этого

<controls:MyCrazyForm runat="server"> 
    <helpTexts> 
     <helpText for="field_Dob"> 
Some rambling nonsense to do with the DOB field 
     </helpText> 
     ... 
    </helpTexts> 
</controls:MyCrazyForm> 

Элементы управления анализируются рекурсивно.

Форма создает набор полей для каждого сегмента, поля создают много полей FieldXXX (где XXX = дата, текст, combobox и т. Д.) В зависимости от типа данных.

Типы FieldXXX создают div, а затем несколько стандартных элементов управления .net (TextBox, DropDownList и т. Д.), Чтобы фактически отобразить себя. Именно в этот момент внутри содержащего div мне нужно вывести текст справки.

Мой вопрос

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

На странице будет только одна из этих форм. Должен ли я сделать форму верхнего уровня как Singleton и получить ее так ...?

Должен ли я передать ссылку на форму в каждый элемент управления вплоть до дерева (это кажется грязным)?

Я в милях от цели архитектуры этой (хотя она работает отлично в данный момент), и я должен посмотреть на другой способ реализации?

Благодаря

ответ

1

Это может быть сложнее сначала, но упрощает обслуживание, почему бы не запустить файл xml с помощью процессора xsl? Файл xslt присваивал бы helptext-узлам вашего файла helptexts соответствующим узлам поля.

<?xml version="1.0" encoding="ISO-8859-1"?> 
<form> 
    <segment> 
     <label>The header</label> 
     <fields> 
      <field> 
       <id>field_name</id> 
       <type>string</type> 
       <label>Name</label> 
       <required>1</required> 
      </field> 
      <field> 
       <id>field_Dob</id> 
       <type>Date</type> 
       <label>Date of Birth</label> 
       <required>1</required> 
      </field> 
     </fields> 
    </segment> 
</form> 

XSLT-файл:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!-- Edited by XMLSpy® --> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 

    <xsl:template match="/form/segment/fields/field[id='field_name']"> 
    <xsl:copy> 
     <xsl:element name="helptext">This is a Name helptext.</xsl:element> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/form/segment/fields/field[id='field_Dob']"> 
    <xsl:copy> 
     <xsl:element name="helptext">This is a Date of birth helptext.</xsl:element> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="node() | text()"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

дает следующее:

<form> 
    <segment> 
     <label>The header</label> 
     <fields> 
      <field> 
<helptext>This is a Name helptext.</helptext> 
       <id>field_name</id> 
       <type>string</type> 
       <label>Name</label> 
       <required>1</required> 
      </field> 
      <field> 
<helptext>This is a Date of birth helptext.</helptext> 
       <id>field_Dob</id> 
       <type>Date</type> 
       <label>Date of Birth</label> 
       <required>1</required> 
      </field> 
     </fields> 
    </segment> 
</form> 

Этот файл XML теперь может быть разобран, как и раньше, но теперь вы можете получить текст справки в то же время, вы генерируете элементы формы. Ваш HTML monkies тогда только нужно отредактировать файл XSLT, или просто включить другой файл:

<xsl:template match="/form/segment/fields/field[id='field_Dob']"> 
    <xsl:copy> 
     <xsl:element name="helptext"> 
     <xsl:copy-of select="document('field_Dob.txt')"/> 
     </xsl:element> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 

Вы можете попробовать XSL онлайн here

+0

Спасибо Озан. Ваше решение кажется мне самым чистым. Это позволяет мне хранить все «как есть» и вводить текст справки в мой основной документ XML. хорошая работа! –

0

насчет перемещения вверх родителей контроля до тех пор, пока не найдешь контроль определенного типа, или с конкретным переменным членом под названием «HelpTexts»?

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

Это было бы использовать API для отражения и обобщенные статические вспомогательные функции, таких как

GetHelpTextFromParent(Control controlParent, string id) 

Это позволило бы проверить controlParent, чтобы увидеть, если она была переменная HelpTexts члена в ней, а затем посмотреть вверх по id helptext.Если нет, он будет рекурсивно вызывать GetHelpTextFromParent с родительским элементом controlParent, до подходящего условия завершения. (Я упоминаю «подходящее условие завершения», потому что, вероятно, это слишком сложно, чтобы вы не дошли до окна рабочего стола, возможно, вам захочется прекратить рекурсию до этого времени, но это будет проблема проверки/отладки.)

0

Если вы используете , анализируя этот XML-код в Control Server и программно генерируя дерево элементов управления, как вы убедитесь, что ребята из HTML синхронизируют эти идентификаторы? Если у них есть доступ к этим XML, возможно, вы должны позволить им добавлять helpTexts прямо там, а не в aspx.

Но, чтобы ответить на ваш вопрос, я предполагаю, что вы разбираете xml после того, как разметка aspx была прочитана и построена, чтобы вы могли индексировать эти тексты непосредственно перед разбором XML. Затем, когда вы на самом деле создаете свое динамическое дерево управления, вы просматриваете свой индекс с помощью идентификатора элемента управления, указанного в вашем исходном xml, и подключайте его к этой точке.

EDIT: Хорошо, в зависимости от того, как вы создаете эти дочерние элементы управления, я бы разоблачил все встроенные helptexts формы внутри, как свойство, проиндексированное идентификатором элемента управления, которое даст вам текст справки или пустую строку. Я не уверен, что получаю MyCrazyForm.Instance.

+0

XML предоставляется сторонним приложением. Невозможно изменить XML в любой разумный временной масштаб. Вот почему я хочу увеличить его с конца ASPX –

+0

Хорошо, теперь я вижу, что вы включаете те тексты внутри своей пользовательской формы. Таким образом, вы должны обрабатывать парсинг XML и синтаксический анализ HelpText внутри вашего настраиваемого элемента управления формой. Как я уже сказал, проанализируйте ваши тексты, затем проанализируйте сторонний XML и объедините их. – user134706

+0

Привет, время выполнения. Я получаю это, и в настоящее время я это делаю. Мой вопрос заключается в том, что такое «ставки» (легкий, самый чистый, самый гибкий?) Способ получения данных, которые анализируются на верхнем уровне (в элементе управления на странице) с помощью трех или четырех уровней элементов управления, где это необходимо. –

0

Я предлагаю создать интерфейс, как этот

interface IHelpTextProvider 
{ 
    Dictionary<string, string> HelpTexts 
    { 
     get; 
    } 
} 

Затем элемент управления формы может реализовать этот интерфейс и передать ссылку на этот интерфейс при создании fieldsets и управления FieldXXX.

В качестве альтернативы вы можете сделать, как предлагалось полиглот, и когда требуется текст справки, управление FieldXXX происходит рекурсивно через своих родителей, пока не будет найден родительский интерфейс, реализующий интерфейс IHelpTextProvider.

0

Вы можете создать событие в серверном элементе управления, которое было бы поднято всякий раз, когда захочет/нуждается текст справки для заданного поля. Форма может подключить обработчик событий и ответить на него. Таким образом, вам не нужно передавать какой-либо объект, чтобы дать серверу доступ к этой информации. Для этого нам нужно сделать три вещи.

Создание класса EventArgs:

class HelpTextEventArgs : EventArgs 
{ 
    public string Text { get; set; } 
    public string FieldId { get; private set; } 
    public HelpTextEventArgs(string fieldId) 
    { 
     FieldId = fieldId; 
    } 
} 

Создать событие в элементе управления сервера:

public event EventHandler<HelpTextEventArgs> HelpTextRequested; 

protected void OnHelpTextRequested(HelpTextEventArgs e) 
{ 
    EventHandler<HelpTextEventArgs> evt = this.HelpTextRequested; 
    if (evt != null) 
    { 
     evt(this, e); 
    } 
} 
// wrapper for the event raising method for easier access in the code 
public string GetHelpText(string fieldId) 
{ 
    HelpTextEventArgs e = new HelpTextEventArgs(fieldId); 
    OnHelpTextRequested(e); 
    return e.Text; 
} 

... и создать обработчик событий в форме, которая может получить доступ тексты справки:

private void Page_Load(object sender, EventArgs e) 
{ 
    ServerControl.HelpTextRequested += ServerControl_HelpTextRequested; 
} 

private void ServerControl_HelpTextRequested(object sender, HelpTextEventArgs e) 
{ 
    e.Text = FindHelpText(e.FieldId); 
} 

Используя этот подход, код будет работать нормально, даже если хостинговая форма не предоставляет помощь xt сервис; серверный контроль не зависит от того, что есть обработчик событий.

1

Как и другие способы передачи информации между элементами управления, поскольку другие ответы здесь выдвигаются, я думаю, что другой подход может быть полезен, в зависимости от специфики вашего дела. Аналогичная проблема с той, которую вы описали, - связывание определенного текста с некоторыми элементами управления в форме - была решена для более общего случая интернационализации с помощью ресурсов. Я знаю, что это отличается от других ответов, а не напрямую о том, что вы задавали в своем вопросе, но ресурсы, похоже, хорошо удовлетворяют потребностям, как описано ниже. Вместо ответа на ваш конкретный вопрос об информационном потоке между элементами управления, я пытаюсь рассмотреть конечный результат, который вы пытаетесь достичь.Поймите меня, если я что-то не понял :-)

  1. Каждая форма и поле в форме имеют уникальную идентификацию. Следовательно, идентификатор ресурса может быть построен однозначно из формы и поля.
  2. Файл источника ресурсов - это просто XML, полностью отделенный от специфики пользовательского интерфейса и может быть передан не разработчикам, чтобы заполнить соответствующий текст справки. Если вы изменили пользовательский интерфейс, этот файл не должен изменяться на всех.
  3. Во время рендеринга вы можете просто получить ресурс для поля в форме, используя свой идентификатор ресурса, и включить текст в пользовательском интерфейсе любым, как вы хотите.
  4. Поскольку такой же подход используется для I18N/L10N, он хорошо документирован, хорошо понят, декларативен, прост и эффективен.
0

Как предложил Ozam, вы можете использовать XSL.

Отдельный XML-файл со структурой, аналогичной структуре стороннего XML-файла, который содержит helpText для XML-узла, был бы хорош &, вам может потребоваться слияние (?) Их в некотором роде.

Я не знаю, если эта помощь в любом случае, вообще.

Смежные вопросы