2014-01-19 2 views
1

Итак, когда я обрабатываю html-шаблоны из javascript (или coffeescript, я использую оба в зависимости от обстоятельств), я считаю, что у меня действительно распространенный случай, который кажется излишним неуклюжий. Например:JS/Coffee + HTML, более простой способ установить условный класс

У меня есть объект JS вроде этого:

var thingy = { 
    name: 'Some Thing', 
    category: 'widget', 
    active: true 
}; 

Я мог бы хотеть, чтобы сделать это в HTML так:

<div class="widget active">Some Thing</div> 

бит, который всегда чувствует себя неуклюжей превращается логическое проверьте javascript в строку класса css. То, что я обычно в конечном итоге делает что-то вроде этого:

function renderThing(thing) { 
    var klass = thing.active ? thing.category + " active" : thing.category 
    return '<div class="'+klass+'">'+thing.name+'</div>'; 
} 

В CoffeeScript это чувствует больше, так как тройная более многословен:

renderThing = (thing) -> 
    klass = if thing.active then thing.category + " active" else thing.category 
    '<div class="'+klass+'">'+thing.name+'</div>' 

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

Итак, мне было интересно, есть ли у кого-нибудь идеи/предложения по более сжатому и/или читабельному способу сделать это?

+0

'Klass = thing.category; if (thing.active) klass + = "active" '? – Bergi

+0

Не могли бы вы уточнить ситуацию «* с тремя из четырех», может быть, пример кода? Вы имеете в виду четырех троичных операторов? Возможна ли петля? – Bergi

+0

@ Bergi yes Я имею в виду несколько тернарных операторов, например, если объект может иметь более одного типа состояния типа 'selected' или' current' или 'active' или' disabled' или 'bookmarked' и т. Д. Я пробовал не дать чрезмерно конкретный пример, потому что я думаю об этом больше, поскольку общая проблема, которую я нахожу, часто встречается в программировании javascript. – Andrew

ответ

1

Если я делаю много из них, то я бы написать простую функцию, более или менее, обеспечить свое собственное «произнесение булевым нанизывать»:

if_true = (f, s) -> 
    return s if(f) 
    return '' 

Затем немного строки интерполяции построить класс строку:

klass = "#{if_true(o.active, 'active')} #{o.category}" 

Если вам не нравится рассеянное пространство, когда !o.active то вы могли бы переместить это пространство в if_true аргумент:

klass = "#{if_true(o.active, 'active ')}#{o.category}" 

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

o = 
    first: true 
    second: true 
    third: false 
    fourth: undefined 
    fifth: 'element' 
    category: 'pancakes' 

flags = [ 'first', 'second', 'third', 'fourth', 'fifth' ] 

klasses = (if_true(o[f], f) for f in flags) 
klasses.push(o.category) 
klass = klasses.join(' ') 

Демо: http://jsfiddle.net/ambiguous/eGDaa/

1

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

Действительно будет. Похоже, идеальное место, чтобы использовать назначьте от переключателя - то есть, если будет только один «надстройка» класс:

score = 76 
grade = switch 
    when score < 60 then 'F' 
    when score < 70 then 'D' 
    when score < 80 then 'C' 
    when score < 90 then 'B' 
    else 'A' 

Но это было бы 1 вход равен 1 выход, который не может быть то, что вы хотите. Может быть, вам нужно:

renderThing = (thing) -> 
    cssClass = thing.category 
    keysToCss = ["active", "disabled", "delta", "gamma", "epsilon"] 

    for k,v of thing 
    if lodash.contains(keysToCss, k) # I'm using lodash here, same as Underscore 
    cssClass += " #{k}" 

    "<div class='#{cssClass}'></div>" 

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

+0

На самом деле, я вообще не смешиваю разметку и код, но почти всегда использую шаблоны javascript, чтобы сохранить разметку из кода. Проблема в том, что в самих шаблонах я часто сталкиваюсь с ситуацией, когда хочу преобразовать определенные атрибуты модели в шаблон имен классов. Обычно я буду писать функцию или что-то вроде 'model.className()', которая выполняет логику, но даже тогда логика оказывается очень сложной, учитывая, что это такая концептуально простая вещь. – Andrew

1

Проверить coffeescripts loop comprehensions итерировать кучу флагов и создать список, который вы можете конкатенировать к значению класса:

renderThing = (thing) -> 
    flags = ["selected", "current", "active", "disabled", "bookmarked"]; 
    klasses = (f for f in flags when thing[f]) 
    klasses.push thing.category 
    "<div class=\"#{klasses.join(" ")}\">#{thing.name}</div>" 
Смежные вопросы