Глядя на контроллер и немного узнавая о том, как работает MVC, я смог понять это.
Мое представление было одним из автоматически сгенерированных и содержало эту строку кода:
@Html.DropDownList("PriorityID", string.Empty)
Чтобы добавить атрибуты html, мне нужно было сделать что-то вроде этого:
@Html.DropDownList("PriorityID", (IEnumerable)ViewBag.PriorityID, new { @class="dropdown" })
Еще раз спасибо @Laurent за вашу помощь, я понимаю, что вопрос wasn 't так ясно, как могло бы быть ...
UPDATE:
Лучшим способом сделать это было бы использовать DropDownListFor , где это возможно, что вы не полагаетесь на магическую строку для атрибута name
@Html.DropDownListFor(x => x.PriorityID, (IEnumerable)ViewBag.PriorityID, new { @class = "dropdown" })
Проблема в том, что Seq
ковариантен по своему параметру типа. Это имеет смысл для большинства его функций. Как неизменяемый контейнер, он действительно должен быть ковариантным. К сожалению, это мешает, когда им нужно определить метод, который принимает некоторые из параметризованных типов. Рассмотрим следующий пример:
trait Seq[+A] {
def apply(i: Int): A // perfectly valid
def contains(v: A): Boolean // does not compile!
}
Проблема в том, что функции всегда контравариантны по своим типам параметров и ковариантны по своим типам возвращаемых данных. Таким образом, метод apply
может возвращать значение типа A
, потому что A
ковариантен вместе с типом возврата для apply
. Однако содержит
не может принимать значение типа A
, потому что его параметр должен быть контравариантным.
Эту проблему можно решить по-разному. Один из вариантов - просто сделать A
параметром инвариантного типа. Это позволяет использовать его как в ковариантном, так и в контравариантном контексте. Однако такая конструкция будет означать, что Seq [String]
не будет , а не подтипом Seq [Any]
. Другой вариант (и наиболее часто используемый) - использовать параметр локального типа, который ограничен снизу ковариантным типом. Например:
trait Seq[+A] {
def +[B >: A](v: B): Seq[B]
}
Этот трюк сохраняет свойство Seq [String] <: Seq [Any]
, а также обеспечивает некоторые очень интуитивно понятные результаты при написании кода, использующего гетерогенные контейнеры. Например:
val s: Seq[String] = ...
s + 1 // will be of type Seq[Any]
Результатом функции +
в этом примере является значение типа Seq [Any]
, потому что Any
является наименее верхним bound (LUB) для типов String
и Int
(другими словами, наименее распространенный супертип). Если задуматься, это именно то поведение, которого мы и ожидали. Если вы создаете последовательность с компонентами String
и Int
, то ее тип должен быть Seq [Any]
.
К сожалению, этот трюк, хотя и применим к таким методам, как contains
, дает некоторые удивительные результаты:
trait Seq[+A] {
def contains[B >: A](v: B): Boolean // compiles just fine
}
val s: Seq[String] = ...
s contains 1 // compiles!
Проблема здесь в том, что мы вызываем метод contains
, передавая значение введите Int
.Scala видит это и пытается вывести тип для B
, который является супертипом как Int
, так и A
, который в данном случае создается как String
. LUB для этих двух типов - Any
(как показано ранее), поэтому экземпляр локального типа для содержит
будет Any => Boolean
. Таким образом, содержит
метод кажется небезопасным по типу.
Этот результат не является проблемой для Map
или Set
, потому что ни один из них не является ковариантным по своим типам параметров:
trait Map[K, +V] {
def contains(key: K): Boolean // compiles
}
trait Set[A] {
def contains(v: A): Boolean // also compiles
}
Короче говоря, Метод contains
для ковариантных типов контейнеров не может быть ограничен приемом только значений типа компонента из-за способа работы типов функций (контравариантных по типам параметров). На самом деле это не ограничение Scala или плохая реализация, это математический факт.
Утешительный приз в том, что на практике это не проблема. И, как упоминалось в других ответах, вы всегда можете определить свое собственное неявное преобразование, которое добавляет «типобезопасный» , содержащий
-подобный метод, если вам действительно нужна дополнительная проверка.
Я слышал об этом из-за изменений в поле базы данных (например, от даты до отметки времени). Возможно, стоит отменить изменения базы данных, если вы можете их протестировать, или проверить .hbm или аннотации, как предложил Сэндс.
-121--2959439-Это функция проектировать калиток. Класс можно использовать для связывания стилей и компонентов.
<form wicket:id="form" id="form>
Также можно попробовать (я никогда этого не делал) setMarkupId . Я не уверен, что это хорошо путь.
-121--3238911-Я не уверен, почему вещи были разработаны таким образом - возможно, чтобы зеркально отразить что-то на Java.
В любом случае, использование образца «сутенер-моя библиотека» более эффективно, чем клонирование в набор:
class SeqWithHas[T](s: Seq[T]) {
def has(t: T) = s.contains(t)
}
implicit def seq2seqwithhas[T](s: Seq[T]) = new SeqWithHas(s)
scala> List("3","5") has 1
<console>:7: error: type mismatch;
found : Int(1)
required: java.lang.String
List("3","5") has 1
^
scala> List("3","5") has "1"
res1: Boolean = false
(Вероятно, вы захотите поместить этот материал и другие удобные вещи в один объект, а затем импортировать MyHandyObject._ в большинство ваших исходных файлов)
Если вы готовы отказаться от Infix в пользу регулярного вызова метода, определение и импорт следующего имеет (...) способ избежать создания экземпляра каждый раз, когда вам нужен тип Безопасный "имеет" тест (стоит во внутренних циклах, например):
def has[T](s: Set[T], t: T) = s.contains(t)
, естественно, набор [T] может быть расслаблен в наименьший конкретный тип, который имеет содержащий метод.