2013-05-22 1 views
5

Ho cercato un knockout per il dynamic data-bind e ho una situazione in cui ho bisogno di un array osservabile per contenere più oggetti osservabili.Gli oggetti osservabili all'interno di observableArray non si aggiornano automaticamente

Questo è il mio codice:

<ul data-bind="foreach: { data: categories, as: 'category' }"> 
    <li> 
     <ul data-bind="foreach: { data: items, as: 'item' }"> 
      <li> 
       <span data-bind="text: category.name"></span>: 
       <span data-bind="text: item"></span> 
       <input type="text" data-bind="value: item"/> 
      </li> 
     </ul> 
    </li> 
</ul> 

$(document).ready(function() { 
      ko.applyBindings(viewModel); 
     }); 

     var viewModel = { 
      categories: ko.observableArray([ 
       { name: 'Fruit', items: [ko.observable('Apple'), ko.observable('Orange'), ko.observable('Banana')] }, 
       { name: 'Vegetables', items: [ko.observable('Celery'), ko.observable('Corn'), ko.observable('Spinach')] } 
      ]) 
     }; 

Quando si lavora con osservabili ogetto di solito ho potuto modificare un valore di una casella di testo di input e che il valore è impostato a tutta pagina in cui che la proprietà è stata usata da visualizzare.

Nell'esempio corrente ho provato a fare lo stesso con la mia casella di input, ma dopo aver modificato i valori nella casella di testo, l'intervallo non ha raggiunto il valore corrente.

Come posso rendere gli oggetti osservabili all'interno del campo osservabile come si comporterebbero se fossero oggetti osservabili autonomi?

risposta

1

quando incontro questi problemi, mi piace suddividerli in sub vms, che mi consentono un migliore controllo su ciò che sta accadendo ad ogni livello di contesto in cui mi trovo. Per i tuoi problemi sopra, vorrei fare qualcosa del genere:

var produceVM = function (data) { 
    var self = this; 

    self.item = ko.observable(data); 
} 

var categoryVM = function (data) { 
    var self = this; 

    self.name = ko.observable(data.name); 
    self.items = ko.observableArray(); 

    var items = ko.utils.arrayMap(data.items, function (item) { 
     return new produceVM(item); 
    }); 

    self.items(items); 
} 

var viewModel = function (data) { 
    var self = this; 

    self.categories = ko.observableArray(); 

    var categories = ko.utils.arrayMap(data, function (category) { 
     return new categoryVM(category); 
    }); 

    self.categories(categories); 
} 

var data = [ 
    { name: 'Fruit', items: [ 'Apple', 'Orange', 'Banana' ] }, 
    { name: 'Vegetables', items: ['Celery', 'Corn', 'Spinach' ]} 
]; 

ko.applyBindings(new viewModel(data)); 

Credo che il plug-in di mappatura ko ottenga qualcosa di simile a questo senza dover scrivere tutto il codice precedente. potresti passargli il modello dei dati e costruire gli osservabili per ogni oggetto.

0

As @nemesv indicato, la risposta si trova proprio sotto l'angolo.

Basta avvolgere ogni elemento dell'array in oggetto e funzionerà perfettamente.

Questo è il modo in cui il modello di vista dovrebbe apparire, e qui è un lavoro jsfiddle

var viewModel = { 
    categories: ko.observableArray([{ 
     name: 'Fruit', 
     items: [ 
      {name: ko.observable('Apple')}, 
      {name: ko.observable('Orange')}, 
      {name: ko.observable('Banana')} 
     ] 
    }, { 
     name: 'Vegetables', 
     items: [ 
      {name: ko.observable('Celery')}, 
      {name: ko.observable('Corn')}, 
      {name: ko.observable('Spinach')} 
     ] 
    }]) 
}; 

Devo dire dalla mia esperienza personale, che di solito avrete oggetti all'interno di matrice comunque, non sostenendo che non vi Non sono altri casi d'uso, solo dicendo che è molto utile avere oggetti in serie e avere la capacità di cambiarli dinamicamente e non preoccuparsi di nient'altro.