Я реализовал как:
public interface Constants{
Integer PAGE_SIZE = 20;
}
-
public class JspConstants extends HashMap<String, String> {
public JspConstants() {
Class c = Constants.class;
Field[] fields = c.getDeclaredFields();
for(Field field : fields) {
int modifier = field.getModifiers();
if(Modifier.isPublic(modifier) && Modifier.isStatic(modifier) && Modifier.isFinal(modifier)) {
try {
Object o = field.get(null);
put(field.getName(), o != null ? o.toString() : null);
} catch(IllegalAccessException ignored) {
}
}
}
}
@Override
public String get(Object key) {
String result = super.get(key);
if(StringUtils.isEmpty(result)) {
throw new IllegalArgumentException("Check key! The key is wrong, no such constant!");
}
return result;
}
}
Следующий шаг поместить экземпляр этого класса в servlerContext
public class ApplicationInitializer implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
sce.getServletContext().setAttribute("Constants", new JspConstants());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
добавить слушателя в web.xml
<listener>
<listener-class>com.example.ApplicationInitializer</listener-class>
</listener>
Доступ к в jsp
${Constants.PAGE_SIZE}
Определите это где-нибудь в вашем представлении / помощниках
@functions {
object getHtmlAttributes (bool ReadOnly, string CssClass)
{
if (ReadOnly) {
return new { @class = CssClass, @readonly = "readonly" };
}
return new { @class = CssClass };
}
}
Затем используйте:
@Html.TextBox("name", "value", @getHtmlAttributes(Model.ReadOnly, "test"))
@Html.TextBoxFor(m => m.FieldName, Html.FixBoolAttributes(new {
@class = "myClass",
@readonly = myFlag
}))
public static class BooleanAttributeFix
{
/// <summary>
/// Normalises HTML boolean attributes so that readonly=true becomes readonly="readonly" and
/// readonly=false removes the attribute completely.
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static RouteValueDictionary FixBoolAttributes(this HtmlHelper htmlHelper, object htmlAttributes)
{
var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
foreach(var attrName in new[] { "disabled", "readonly" })
{
object value;
if(attrs.TryGetValue(attrName, out value))
{
if(isTruthy(value))
{
// Change from readonly="true" to readonly="readonly"
attrs[attrName] = attrName;
}
else
{
// Remove attribute entirely
attrs.Remove(attrName);
}
}
}
return attrs;
}
/// <summary>
/// Apply similar loose rules like javascript does for whether a value is true or not.
/// e.g. 1 = true, non-empty string = true and so on.
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
private static bool isTruthy(object val)
{
if(val == null)
return false;
if(val is string)
{
return !String.IsNullOrEmpty((string)val);
}
Type t = val.GetType();
if(t.IsValueType && Nullable.GetUnderlyingType(t) == null)
{
// If a non-nullable value type such as int we want to check for the
// default value e.g. 0.
object defaultValue = Activator.CreateInstance(t);
// Use .Equals to compare the values rather than == as we want to compare
// the values rather than the boxing objects.
// See http://stackoverflow.com/questions/6205029/comparing-boxed-value-types
return !val.Equals(defaultValue);
}
return true;
}
}
Вот мой ответ по этому аналогичному вопросу: https://stackoverflow.com/a/13922813/495000
Создал следующий Помощник - он берет boolean и анонимный объект. Если значение отключено, оно добавляет отключенный атрибут анонимному объекту (который фактически является словарем) со значением «отключено», в противном случае он вообще не добавляет свойство.
public static RouteValueDictionary ConditionalDisable(
bool disabled,
object htmlAttributes = null)
{
var dictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
if (disabled)
dictionary.Add("disabled", "disabled");
return dictionary;
}
пример этого в действии:
@Html.TextBoxFor(m => m.SomeProperty,
HtmlHelpers.ConditionalDisable(true, new { @class = "someClass"))
. Огромное преимущество для этого подхода для меня заключалось в том, что он работает практически со всеми MVC HtmlHelpers, поскольку все они имеют Overloads, которые принимают RouteValueDictionary вместо анонимного объекта.
Предостережения: HtmlHelper.AnonymousObjectToHtmlAttributes()
использует некоторую работу ниндзя причудливого кода, чтобы все было сделано. Я не совсем уверен, насколько он эффективен ... но этого было достаточно для того, для чего я его использую. Ваш пробег может отличаться.
Мне не особенно нравится его название, но я не мог придумать ничего лучшего. Переименование очень просто.
Я также не люблю синтаксис использования, но опять-таки я не мог придумать ничего лучшего. Это не должно быть трудно изменить. Метод расширения на объекте - это одна идея ... в итоге вы получите new { @class = "someClass" }.ConditionalDisable(true)
, но если вам нужен только атрибут disable и у вас нет ничего лишнего, чтобы добавить вас в нечто вроде грубого, как new {}.ConditionalDisable(true);
, а вы также заканчивается методом расширения, который отображается для всех object
... что, вероятно, нежелательно.
Выполнение добавления отключенной клиентской стороны атрибута работает для меня. Обратите внимание, что вы должны проверить, какие поля разрешены для редактирования на стороне сервера, но это верно для того, где атрибут disabled объявлен также декоративно.
В этом примере я отключил все элементы формы, используя jQuery.
if (Model.CanEdit)
{
<script type="text/javascript">
$(document).ready(function() {
$('#editForm *').attr('disabled', true);
});
</script>
}
Что вы думаете о моем простом решении? Он легко работает с обоими возможными типами HtmlAttributes
:
Dictionary<string, object>
Anonymous Object
: Сначала добавьте следующее простой extension class
к вашему проекту:
public static class HtmlAttributesExtensions
{
public static IDictionary<string, object> AddHtmlAttrItem(this object obj, string name, object value, bool condition)
{
var items= !condition ? new RouteValueDictionary(obj) : new RouteValueDictionary(obj) {{name, value}};
return UnderlineToDashInDictionaryKeys(items);
}
public static IDictionary<string, object> AddHtmlAttrItem(this IDictionary<string, object> dictSource, string name, object value, bool condition)
{
if (!condition)
return dictSource;
dictSource.Add(name, value);
return UnderlineToDashInDictionaryKeys(dictSource);
}
private static IDictionary<string, object> UnderlineToDashInDictionaryKeys(IDictionary<string,object> items)
{
var newItems = new RouteValueDictionary();
foreach (var item in items)
{
newItems.Add(item.Key.Replace("_", "-"), item.Value);
}
return newItems;
}
}
Теперь в режиме просмотра:
Пример1 (HtmlAttributes
type as Anonymous Object
)
@{
var hasDisabled=true;
}
@Html.CheckBox("CheckBox1"
, true
, new { @class = "Class1"}
.AddHtmlAttrItem("disabled", "disabled", hasDisabled))
.
Пример 2 (HtmlAttributes
type as Dictionary<string, object>
)
@Html.CheckBox("CheckBox1"
, true
, new Dictionary<string, object> { { "class", "Class1" }
.AddHtmlAttrItem("disabled", "disabled", hasDisabled))
.
Теперь просто измените значение
blockquote>hasDisabled
кtrue
илиfalse
!
Example3 (Несколько условных свойств)
@{ var hasDisabled=true; var hasMax=false ; var hasMin=true ; } @Html.CheckBox("CheckBox1" , true , new { @class = "Class1"} .AddHtmlAttrItem("disabled", "disabled", hasDisabled) .AddHtmlAttrItem("data-max", "100", hasMax) .AddHtmlAttrItem("data-min", "50", hasMin)) .
HtmlHelper.AnonymousObjectToHtmlAttributes
вместо UnderlineToDashInDictionaryKeys
, потому что он уже встроен. ;)
– Rami A.
23 June 2018 в 01:09
Если вам нужен более краткий синтаксис, не требующий вспомогательной функции, вы можете использовать трехмерный оператор при определении словаря, используемого для html-атрибутов @ HTML.Checkbox helper ...
@Html.CheckBox("CheckBox1", true, Model.ReadOnly
? new { @class = "Class1", @disabled = Model.ReadOnly }
: null)
В этом случае Model.ReadOnly является false, null передается как словарь атрибутов html.
disable
опционально? – Juan Carlos Oropeza 24 April 2018 в 20:28