2013-01-04 8 views
24

Qual è il modo suggerito "best practice" per usare "attr" Dati di Knockout vincolanti con gli attributi standalone come "sola lettura" e "disabile"?Knockout attr vincolante con attributi come 'sola lettura' e 'disattivato'

Questi attributi sono speciale in quanto sono generalmente abilitati impostando il valore dell'attributo al nome di attributo (anche se molti browser funzionano bene se semplicemente includere i nomi degli attributi, senza alcun valore nel codice HTML):

<input type="text" readonly="readonly" disabled="disabled" value="foo" /> 

Tuttavia, se non si fa vogliono questi attributi da applicare, la prassi generale è semplicemente omettere del tutto dal codice HTML (in contrapposizione a fare qualcosa di simile in sola lettura = "false"):

<input type="text" value="foo" /> 

L'associazione dati "attr" di Knockout non supporta questo scenario. Appena ho fornire un nome di attributo, ho bisogno di fornire un valore così:

<input type="text" data-bind="attr: { 'disabled': getDisabledState() }" /> 

Esiste un modo cross-browser spegnere 'disabile' o 'sola lettura'? O c'è un trucco con una rilegatura personalizzata che posso usare per non rendere nulla se non voglio l'elemento disabilitato o reso di sola lettura?

+0

Non capisco, perché è necessario fornire disabilitata se non disattivato per mostrare ancora? – jjperezaguinaga

+0

L'esempio che ho dato è stato progettato per dimostrare semplicemente il problema. Il problema è questo: alcuni attributi in HTML sono attributi standalone - non richiedono realmente un valore. E se non vuoi che questi attributi influenzino l'HTML, li devi semplicemente omettere. Ma il meccanismo di intercettazione dati "attr" di Knockout non supporta questo scenario. –

risposta

35

Il binding di dati "attr" di Knockout supporta questo scenario solo restituire null o undefined dalla funzione getDisabledState() quindi non emetterà l'attributo.

Demo Fiddle.

+0

Come posso verificare che l'attributo non sia stato emesso usando Firebug o uno strumento simile? Quando provo a visualizzare l'HTML "live" dalla demo Fiddle in alto, visualizzo ancora il codice di Knockout data binding, non i live, resi i tag . (Tuttavia, ammetto che non mi è mai venuto in mente di farlo: nella mia funzione getDisabledState(), restituivo sempre "disabled" o la stringa vuota ""). –

+0

Se il mio violino funziona con il tuo browser, allora funziona. Non uso Firebug. Negli strumenti di sviluppo di Chrome è chiaro che aggiunge e rimuove l'attributo se restituisci "disabilitato" e "non definito". – nemesv

+0

OK. Ho verificato questo utilizzando Chrome. Grazie per la rapida risposta e la demo Fiddle.È una soluzione semplice ed elegante che non mi è mai venuta in mente. In genere, inizializzo i miei valori restituiti al tipo di dati previsto (che per 'disabled' o 'readonly' è una stringa). Inizializzerò semplicemente a "indefinito" e dovrei essere pronto. Grazie! –

7

Knockout ha un binding enable e un binding disable.

Non sono sicuro se questi erano disponibili quando la domanda è stata posta, ma chiunque faccia riferimento a questo problema dovrebbe essere a conoscenza.

+1

Assicurati di scegliere quello giusto. '! osservableProperty' non funziona. Il NOT '!' Non viene rilevato dal valutatore. –

+4

! ObservableProperty() funziona però :) molto più veloce e spesso più pulito di un binding personalizzato – mikus

+1

@ P.Brian.Mackey Questo è un errore principiante Knockout comune. Quando aggiungi un operatore come! di fronte a una proprietà osservabile, è necessario chiamarlo esplicitamente aggiungendo() alla fine di propertyName. Questo dice a Knockout di sollevare l'intera espressione in un sintetico calcolato. Se utilizzi Chrome Debugger e inserisci una proprietà osservabile falsa che non esiste, genererà un errore con una VM: SomeLineNumber nella console. Fai clic sulla VM: SomeLineNumber e vedrai cosa ha generato Knockout. –

9

è anche possibile creare un binding per sola lettura come questo:

ko.bindingHandlers['readonly'] = { 
'update': function (element, valueAccessor) { 
    var value = ko.utils.unwrapObservable(valueAccessor()); 
    if (!value && element.readOnly) 
     element.readOnly = false; 
    else if (value && !element.readOnly) 
     element.readOnly = true; 
} 
}; 

Fonte: https://github.com/knockout/knockout/issues/1100

+0

Grazie per aver condiviso la fonte e incluso il codice in linea. –

Problemi correlati