2012-11-27 9 views
8

Mam następujące modele:nokaut powiązać obiekt wartość klucza do rozwijanej

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; 
    }); 
} 

Chcę zaoferować rozwijaną, aby wybrać kategorię, ale nie mam pojęcia jak to powiązać. Być może użyłem niewłaściwego podejścia z moimi modelami, ale to najprawdopodobniej, jak otrzymam moje dane z serwera, więc próbowałem owijać mój JS wokół tego.

Próbowałem coś takiego:

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

Ale ja nie rozumiem, jak połączyć wartość rozwijaną do modelu categoryId. To jest a fiddle z obowiązującym wiązaniem dla właściwości name

Odpowiedz

21

W polu listy należy podać: options, optionsText, optionsValue i value. value (która jest aktualnie wybraną wartością) powinna wskazywać na swoją model.categoryId(). I optionsValue jest nazwa właściwości gdzie można uzyskać wartości dla listy:

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

i to wszystko. I działające skrzypce: http://jsfiddle.net/Y7Nrc/

+0

thx za tę szybką i użyteczną odpowiedź :) – kannix

10

Zgodnie z odpowiedzią Maxa Schmelevsa, która jest prawidłowa, ta funkcjonalność nie zmienia obiektu JSON podczas zmiany pozycji z rozwijanego menu.

Więc oto moje poprawki do swojego kodu:

HTML kod:

<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> 

kod 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')); 

!!! WAŻNE !!!

Jeśli to podejście odpowiada na twoje pytanie, proszę wybrać odpowiedź Maxa Shmeleva jako poprawną, nie moją, ponieważ właśnie dodałem kilka uwag do jego kodu.

+0

+1 za udzielenie kredytu tam, gdzie jest należne. – ryadavilli

+0

Dziękuję bardzo za tę odpowiedź. Zmieniłem 'self.categoryId = ko.observable (1);' na 'self.categoryId = ko.observable();' a teraz wszystko działa jak czar :) – kannix

Powiązane problemy