2012-11-27 10 views
8

ho i seguenti modelli:knockout associare un oggetto di valore chiave per dropdown

var allCategories = [{ 
    id: 1, 
    name: 'Red'}, 
{ 
    id: 5, 
    name: 'Blue'}]; 

function model() { 
    self = this; 
    self.name = ko.observable(""); 
    self.categoryId = ko.observable(-1); 
    self.categoryName = ko.computed(function() { 
     if (self.categoryId() == -1) return ""; 
     return getCategoryNameById(self.categoryId()).name; 
    }); 
} 

function getCategoryNameById(id) { 
    return _.find(allCategories, function(cat) { 
     return cat.id == id; 
    }); 
} 

voglio offrire un menu a tendina per selezionare la categoria ma non ho idea di come vincolare tale. Forse ho usato l'approccio sbagliato con i miei modelli, ma è più probabile che ottenga i miei dati dal server, quindi ho provato a racchiudere il mio JS.

Ho provato qualcosa di simile:

<select data-bind="options: categories, optionsText: 'name', value: 'id', optionsCaption: 'Categorie...'"></select> 

Ma non capisco come collegare il valore di discesa per il modello categoryId.

Qui è a fiddle con un collegamento funzionante per la proprietà nome.

risposta

21

Per la casella di riepilogo è necessario specificare: options, optionsText, optionsValue e value. value (che è il valore attualmente selezionato) dovrebbe puntare al numero model.categoryId(). E optionsValue è il nome della proprietà dove trovare i valori per la lista:

<select data-bind="options: categories, optionsText: 'name', optionsValue: 'id', value: $root.model.categoryId(), optionsCaption: 'Categorie...'"></select> 

E questo è tutto. E il violino funzionante: http://jsfiddle.net/Y7Nrc/

+0

thx per questa risposta rapida e utile :) – kannix

10

In base alla risposta di Max Schmelevs, che è corretta, questa funzionalità non cambia l'oggetto JSON quando si modifica l'elemento da un menu a discesa.

Così qui sono le mie correzioni per il suo codice: Codice

HTML:

<div id="container"> 
    <!-- Here I've added valueUpdate on keydown --> 
    <input data-bind="value: model.name, valueUpdate:'afterkeydown'" /> 
    <!-- NOTE: Here you should call value like $root.model.categoryId --> 
    <select data-bind="options: categories, optionsText: 'name', optionsValue: 'id', value: $root.model.categoryId, optionsCaption: 'Categorie...'"></select> 
    <span data-bind="text: ko.toJSON($data.model)"></span> 
</div> 

codice JavaScript:

var allCategories = [ 
    {id: 1, name: 'Red'}, 
    {id: 5, name: 'Blue'}]; 

function model() { 
    self = this; 
    self.name = ko.observable(""); 
    self.categoryId = ko.observable(1); 
    self.categoryName = ko.computed(function() { 
    //NOTE: Here we should check if categoryId() is defined or not 
    if (!self.categoryId()) return ""; 
     return getCategoryNameById(self.categoryId()).name; 
    }); 
} 

function getCategoryNameById(id) { 
    return _.find(allCategories, function(cat) { 
     return cat.id == id; 
    }); 
} 

var viewModel = {}; 
viewModel.model = new model(); 
viewModel.categories = allCategories; 
ko.applyBindings(viewModel, document.getElementById('container')); 

!!! IMPORTANTE !!!

Se questo approccio risponde alla tua domanda, seleziona la risposta di Max Shmelev come corretta, non mia, perché ho appena inserito alcune osservazioni nel suo codice.

+0

+1 per dare credito dove è dovuto. – ryadavilli

+0

grazie mille per questa risposta. Ho cambiato 'self.categoryId = ko.observable (1);' a 'self.categoryId = ko.observable();' e ora tutto funziona come un fascino :) – kannix

Problemi correlati