2013-05-21 13 views
8

Ho una tabella in questo modo:knockout foreach nel bel mezzo di un tavolo

<table> 
<thead> 
    <tr> 
    <td>Column 1</td><td>Column 2</td> 
    </tr> 
</thead> 
    <tr> 
    <td>static 1a</td><td>static 2a</td> 
    </tr> 
    <tr> 
    <td>dynamic 1b</td><td>dynamic 2b</td> 
    </tr> 
    <tr> 
    <td>dynamic 1c</td><td>dynamic 2c</td> 
    </tr> 
</table> 

I campi dinamici bisogno di essere un foreach per iterare eliminazione diretta tutte le proprietà dell'oggetto. L'unica cosa che posso pensare di fare è qualcosa di simile:

<tbody data-bind="foreachprop: properties"> 
     <tr><td><span data-bind="text: propertyName"></span></td><td><span data-bind="text: value"></span></td></tr> 
    </tbody> 

Quali opere tecnicamente, ma le viti con il mio stile perché la riga statica dovrebbe essere parte del tbody. Cos'altro posso associare a ciascuno di essi? Devo perdere una soluzione semplice.

aggiornamento: In realtà non sto usando "foreach", sto usando una funzione personalizzata che itera attraverso le proprietà. Quando provo ad usare < - ko foreachprop:! > proprietà - ricevo il seguente errore console:

Uncaught Error: The binding 'foreachprop' cannot be used with virtual elements

Ecco la funzione foreachprop

ko.bindingHandlers.foreachprop = { 
    transformObject: function (obj) { 
     var properties = []; 
     for (var key in obj) { 
      if (obj.hasOwnProperty(key)) { 
       var newObj = obj[key]; 
       newObj.propertyName = key; 
       properties.push(newObj); 
      } 
     } 
     return properties; 
    }, 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var value = ko.utils.unwrapObservable(valueAccessor()), 
      properties = ko.bindingHandlers.foreachprop.transformObject(value); 
     ko.applyBindingsToNode(element, { foreach: properties }); 
     return { controlsDescendantBindings: true }; 
    } 
}; 

risposta

14

È possibile utilizzare foreach senza un elemento contenitore (documentazione: note 4) Per gestire ciò, è possibile utilizzare la sintassi del flusso di controllo senza contenitore . Hai solo bisogno di una riga di commento specfial dove si può mettere il foreach:

<tbody data-bind=""> 
    <tr> 
    <td>static 1a</td><td>static 2a</td> 
    </tr> 
    <!-- ko foreach: properties --> 
     <tr> 
     <td> 
      <span data-bind="text: propertyName"></span> 
     </td> 
     <td> 
      <span data-bind="text: value"></span> 
     </td> 
    </tr> 
    <!-- /ko --> 
</tbody> 

Se si utilizza un vincolante foreachprop allora è necessario configurare il lavoro con elementi virtuali personalizzati. Si può fare con dopo la dichiarazione bindingHandlers con:

ko.virtualElements.allowedBindings.foreachprop = true; 

Si dovrebbe notare che potrebbe essere necessario riscrivere la logica di manipolazione del DOM all'interno del vostro legame per supportare gli elementi virtuali personalizzati. È possibile trovare un'ampia documentazione sugli helper virtualElements nella documentazione: Creating custom bindings that support virtual elements

+0

Steve Sanderson è un genio. – MrBoJangles

+0

Eventuali effetti collaterali di farlo in questo modo? Cambiamenti delle prestazioni, ecc.? –

+0

Cattive notizie, aggiornando la mia domanda. Scusate. –

0

Mi sono anche reso conto che è possibile avere più elementi tbody in una tabella. Questa soluzione risolve il mio problema quindi ho pensato di condividerlo, ma mi piace nemesv è meglio.

+1

è possibile ma devi ricordare che ogni persona ha il suo contatore di linee. È utile quando si applica lo stile su tutte le altre linee (vedere http://www.w3.org/Style/Examples/007/evenodd.en.html) –

Problemi correlati