2012-10-18 15 views
40

La libreria di knockout.js ha uno "attr" data binding che consente di modificare dinamicamente il valore di un attributo di elemento HTML (ad esempio il "titolo"). Tuttavia, in alcuni casi, l'attributo può o non può essere necessario a seconda del corrispondente osservabile sull'oggetto associato. Ad esempio, se il mio modello ha un osservatore "titolo", potrei voler impostare l'attributo "titolo" se è presente (non nullo) o saltare l'attributo interamente se non è presente (null).Aggiungi un attributo elemento in knockout.js

Il knockout fornisce un modo per impostare in modo condizionale un attributo? (Idealmente senza condizionale rendere l'intero elemento tag di apertura ...)

[Nota] Questa domanda nome simile è stato effettivamente risolto la gestione speciale di eliminazione diretta di classi CSS e non si riferisce a questa domanda (o il proprio titolo) : How to conditionally render an css class with knockoutjs

+1

Penso che questo sia il comportamento di default se i rendimenti osservabili è null, ma posso sbagliarmi. Posso chiederti perché hai bisogno di impostare esplicitamente l'attributo invece di title = "" in caso di un valore vuoto? –

risposta

67

Avevo bisogno di questo quando si seleziona un (che stavo generando manualmente invece di knockout incorporato).

<option 
data-bind="text: text, 
    attr:{ 
    value:value, 
    'selected': typeof(selected) !== 'undefined' ? selected : null 
    }"> 
Choice X 
</option> 

che indica di aggiornare sempre l'attributo di 'testo' e di aggiungere l'attributo 'valore', ma solo aggiungere 'selezionato' se i dati ha già un valore di 'selezionato' definito.

+6

quindi in pratica metti 'null' come valore di attributo e non renderà l'attributo, bello! – root

+2

Questa dovrebbe essere la risposta convalidata. Risponde perfettamente alla domanda nel modo più semplice. –

+1

Sono d'accordo che questa dovrebbe essere la risposta accettata. Mentre la creazione di un'associazione personalizzata funzionerà assolutamente, è più semplice e affronta la domanda più direttamente. – kiprainey

29

È possibile creare un binding personalizzato attrIf che verificherà il valore di uno specifico booleano osservabile prima di aggiungere o meno gli attributi. Vedi questo esempio:

ko.bindingHandlers.attrIf = { 
    update: function (element, valueAccessor, allBindingsAccessor) { 
     var h = ko.utils.unwrapObservable(valueAccessor()); 
     var show = ko.utils.unwrapObservable(h._if); 
     if (show) { 
      ko.bindingHandlers.attr.update(element, valueAccessor, allBindingsAccessor); 
     } else { 
      for (var k in h) { 
       if (h.hasOwnProperty(k) && k.indexOf("_") !== 0) { 
        $(element).removeAttr(k); 
       } 
      } 
     } 
    } 
}; 

<a href="#" data-bind="attrIf: {title: title, _if: flag}">link</a> 
+0

Brillante, ma un problema serio, se ho un attributo diverso da "titolo" e non voglio che si applichi ad esso ... Il _if lo farebbe comunque. Tuttavia, l'idea del codice è buona. – Phil

+5

puoi sempre aggiungere l'altro attributo usando il binding standard ko "attr" (che non è influenzato dal flag _if). esempio: data-bind = "attrIf: {title: title, _if: flag}, attr: {otherAttr: val}" – gbs

+0

mi piacerebbe avere un po 'di logica in più sulla rimozione in basso ... questa risposta non funziona se si desidera eseguire l'override condizionale di un attributo già esistente sull'elemento. immagina il seguente MrTristan

2

Vorrei poter avere appena risposto a @ gbs, ma non posso. La mia soluzione sarebbe stata quella di avere due dello stesso elemento HTML, uno con l'attributo, uno senza, e una condizione a eliminazione diretta per aggiungerne uno in base all'elemento. So anche su questo custom biding, ma quale soluzione è più efficiente?

+0

E cosa fai se hai 5 attributi diversi per lo stesso elemento? Molto divertimento in prospettiva ... – Samuel

Problemi correlati