MVC DropdownlistFor не получает выбранное значение из модели [дубликат]

Обновить

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

  • Лучшая производительность чем прослушивание событий прокрутки
  • Работает в кросс-доменных iframe
  • Может определить, что элемент препятствует / пересекает другой

Intersection Observer находится на своем способ стать полноправным стандартом и уже поддерживается в Chrome 51+, Edge 15+ и Firefox 55+ и находится в разработке для Safari. Существует также polyfill .


Предыдущий ответ

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

  • Скрыт другим элементом перед тестируемым
  • Вне видимой области элемента parent или ancestor
  • Элемент или его дочерние элементы скрыты с помощью свойства CSS clip

Эти ограничения демонстрируются в следующих результатах простого теста :

Failed test, using isElementInViewport [/g11]

Решение: isElementVisible()

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

function isElementVisible(el) {
    var rect     = el.getBoundingClientRect(),
        vWidth   = window.innerWidth || doc.documentElement.clientWidth,
        vHeight  = window.innerHeight || doc.documentElement.clientHeight,
        efp      = function (x, y) { return document.elementFromPoint(x, y) };     

    // Return false if it's not in the viewport
    if (rect.right < 0 || rect.bottom < 0 
            || rect.left > vWidth || rect.top > vHeight)
        return false;

    // Return true if any of its four corners are visible
    return (
          el.contains(efp(rect.left,  rect.top))
      ||  el.contains(efp(rect.right, rect.top))
      ||  el.contains(efp(rect.right, rect.bottom))
      ||  el.contains(efp(rect.left,  rect.bottom))
    );
}

Тест прохождения: http://jsfiddle.net/AndyE / cAY8c /

И результат:

Passed test, using isElementVisible [/g12]

Дополнительные примечания

[ Однако этот метод не лишен собственных ограничений. Например, проверяемый элемент с более низким z-индексом, чем другой элемент в том же месте, будет идентифицирован как скрытый, даже если элемент впереди фактически не скрывает какой-либо его части. Тем не менее, этот метод имеет свои применения в некоторых случаях, когда решение Дэна не распространяется.

Оба element.getBoundingClientRect() и document.elementFromPoint() являются частью спецификации рабочего проекта CSSOM и поддерживаются, по крайней мере, в IE 6 и позже и большинство настольных браузеров в течение длительного времени (хотя и не совсем). См. Quirksmode для этих функций для получения дополнительной информации.

contains() используется, чтобы увидеть, является ли элемент, возвращаемый document.elementFromPoint() дочерним узлом тестируемого элемента для видимость. Он также возвращает true, если возвращаемый элемент является одним и тем же элементом. Это просто делает проверку более надежной. Он поддерживается во всех основных браузерах, Firefox 9.0 является последним из них, чтобы добавить его. Для более старой поддержки Firefox проверьте историю этого ответа.

Если вы хотите проверить больше точек вокруг элемента для видимости, т. Е. Убедиться, что элемент не покрыт более, чем, скажем, 50% это не займет много времени, чтобы отрегулировать последнюю часть ответа. Однако имейте в виду, что это, вероятно, будет очень медленным, если вы проверили каждый пиксель, чтобы убедиться, что он был на 100% видимым.

7
задан VansFannel 24 May 2016 в 08:10
поделиться

2 ответа

К сожалению, @Html.DropDownListFor() ведет себя несколько иначе, чем другие помощники при рендеринге элементов управления в цикле. Об этом ранее сообщалось как о проблеме с CodePlex (не уверен, что ее ошибка или просто ограничение)

. Это 2 варианта для решения этой проблемы, чтобы обеспечить выбор правильной опции на основе свойства модели

Вариант 1 (с использованием EditorTemplate)

Создайте пользовательский EditorTemplate для типа в коллекции. Создайте парциальное значение в /Views/Shared/EditorTemplates/AggregationLevelConfiguration.cshtml (обратите внимание, что имя должно соответствовать имени типа

@model yourAssembly.AggregationLevelConfiguration
@Html.DropDownListFor(m => m.HelperCodeType, (SelectList)ViewData["CodeTypeItems"])
.... // other properties of AggregationLevelConfiguration

, а затем в главном представлении передать SelectList в EditorTemplate как additionalViewData

@using (Html.BeginForm())
{
  ...
  @Html.EditorFor(m => m.Configurations , new { CodeTypeItems = Model.CodeTypeItems })
  ...

Вариант 2 (сгенерируйте новую SelectList на каждой итерации и установите selectedValue)

В этом параметре ваше свойство CodeTypeItems должно быть IEnumerable<GenericIdNameType>, а не SelectList (или просто сделать codeTypes общедоступным свойством). Затем в главном представлении

@Html.DropDownListFor(m => m.Configurations[0].HelperCodeType, new SelectList(Model.CodeTypeItems, "Id", "Name", Model.Configurations[0].HelperCodeType)

Сторона примечания: нет необходимости использовать new { id = "Configurations[0].HelperCodeType" - метод DropDownListFor() уже сгенерированный атрибут id

15
ответ дан Stephen Muecke 27 August 2018 в 00:55
поделиться

Я написал этот класс, чтобы преодолеть проблему, которую я имел с выбором опции в списке выбора html. Я надеюсь, что это кому-то поможет.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace Login_page.Models
{
    public class HTMLSelect
    {
        public string id { get; set; }
        public IEnumerable<string> @class { get; set; }
        public string name { get; set; }
        public Boolean required { get; set; }
        public string size { get; set; }
        public IEnumerable<SelectOption> SelectOptions { get; set; }

        public HTMLSelect(IEnumerable<SelectOption> options)
        {

        }

        public HTMLSelect(string id, string name)
        {
            this.id = id;
            this.name = name;
        }

        public HTMLSelect(string id, string name, bool required, IEnumerable<SelectOption> options)
        {
            this.id = id;
            this.name = name;
            this.required = required;
        }

        private string BuildOpeningTag()
        {
            StringBuilder text = new StringBuilder();
            text.Append("<select");
            text.Append(this.id != null ? " id=" + '"' + this.id + '"' : "");
            text.Append(this.name != null ? " name=" + '"' + this.name + '"' : "");
            text.Append(">");
            return text.ToString();

        }

        public string GenerateSelect(IEnumerable<SelectOption> options)
        {
            StringBuilder selectElement = new StringBuilder();
            selectElement.Append(this.BuildOpeningTag());
            foreach (SelectOption option in options)
            {
                StringBuilder text = new StringBuilder();
                text.Append("\t");
                text.Append("<option value=" + '"' + option.Value + '"');
                text.Append(option.Selected != false ? " selected=" + '"' + "selected" + '"' + ">" : ">");
                text.Append(option.Text);
                text.Append("</option>");
                selectElement.Append(text.ToString());
            }
            selectElement.Append("</select");
            return selectElement.ToString();
        }
    }

    public class SelectOption
    {
        public string Text { get; set; }
        public Boolean Selected { get; set; }
        public string Value { get; set; }
    }
}

И

public IEnumerable<SelectOption> getOrderTypes()
{
    List<SelectOption> orderTypes = new List<SelectOption>();
                        if (this.orderType == "OptionText")
                        {
                            orderTypes.Add(new SelectOption() { Value = "1", Text = "OptionText", Selected = true });
                        } else
                        {
                            orderTypes.Add(new SelectOption() { Value = "2", Text = "OptionText2" });
                        }
}

И использовать его:

@{
    Login_page.Models.HTMLSelect selectElement = new Login_page.Models.HTMLSelect("order-types", "order-types");

}
@Html.Raw(selectElement.GenerateSelect(Model.getOrderTypes()));
0
ответ дан Brandon Minnick 27 August 2018 в 00:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: