2015-05-06 17 views
7

sto cercando knockout se o visibili migliori pratiche in questo caso:Knockout best practice. Se o visibile

<div data-bind="visible: $root.obsVar()"> 
    ... 
    <input type="text" data-bind="value: $root.obsVar().someField" /> 
    ... 
</div> 

Nel caso in cui $root.obsVar() è indefinito, saranno gettati errore. Se si modifica visible in if, il problema salterà, ma è necessario riscrivere l'html. Se c'è un sacco di murkup in div, ci vuole un sacco di tempo. Ci sono motivi per cambiare $root.obsVar().someField a $root.getSomeFieldValue che restituisce sempre il valore corretto o indefinito? O forse ci sono altre tecniche per non sovraccaricare ed evitare errori.

+0

In questo scenario, 'if' o' with' sarebbe la cosa più corretta da fare. Anche * dovrebbe * essere facile da fare. – CrimsonChris

risposta

7

Dipende davvero dallo scenario. Dal docs:

if svolge un ruolo simile a quello visible vincolante. La differenza è che, con visible, il markup contenuto rimane sempre nel DOM e ha sempre gli attributi data-bind applicati - l'associazione visible utilizza solo i CSS per attivare la visibilità dell'elemento contenitore. L'associazione if, tuttavia, aggiunge o rimuove fisicamente la marcatura contenuta nel DOM e applica solo i collegamenti ai discendenti se l'espressione è vera.

Nel vostro scenario, l'unico modo per evitare un errore senza usare if, quando someField è nullo, è quello di fare qualcosa in questo senso:

data-bind="value: ($root.obsVar() == null) ? null : $root.obsVar().someField" 

che è davvero fastidioso dover scrivere ogni volta si accede a una proprietà. Rende il codice più difficile da mantenere e rende più facile commettere un errore, specialmente quando si aggiunge una nuova associazione a una proprietà di obsVar perché sarà necessario ricordarsi di eseguire tale controllo Null.

A meno che non si vedano alcuni chiari vantaggi in termini di prestazioni dall'utilizzo di visible nella propria situazione, la mia raccomandazione sarebbe quella di andare con if perché in tal caso è sufficiente scrivere il controllo in un'unica posizione e non in più posizioni.

+0

Grazie mille. Temevo che mancasse un modo vero per organizzare il codice js. – user3272018

0

Provare a utilizzare $ root.obsVar senza il(). Questo dovrebbe funzionare sia se sia visibile. La differenza tra i due è che "visibile" nasconde semplicemente il div, che sarà ancora presente nel DOM, ma "se" lo lascia fuori dal DOM.

+1

Il problema non in '$ root.obsVar()' ma in '$ root.obsVar(). SomeField' perché non è possibile ottenere' someField' di 'undefined'. Ma se si usa 'se' allora quella parte di codice non esiste e il codice non viene eseguito. – user3272018

1

Come indicato nella risposta di David Sherret, la differenza principale è che con if gli elementi DOM scompaiono se la condizione non è soddisfatta e con visible sono semplicemente nascosti, ma sono sempre presenti nell'albero DOM.

La principale conseguenza è che se si utilizza if e si devono gestire eventi, è necessario utilizzare eventi delegati o allegarli ogni volta che gli elementi vengono ricreati. Quando usi KO di solito non gestisci eventi, perché usi binding come click che sono gestiti da KO e quindi non hai questo problema. Ma puoi avere altri framework coinvolti, come validatori, selettori di date dell'interfaccia utente jQuery e così via, che avranno problemi a funzionare correttamente con KO if.

0

Potrebbe essere necessario utilizzare entrambi.

Utilizzare if per rimuovere il markup dal DOM - prevenire possibili errori JS e quindi non occupa spazio sulla pagina.

E quindi utilizzare visible per nascondere l'elemento fino a quando la pagina non è completamente caricata.

<!-- ko if: whatever --> 
<div data-bind="visible: true" style="display: none"> 
    my content 
</div> 
<!-- /ko -->