Reputation: 328
I am new to knockout, and have a problem getting a selected value from dropdown list. I tried to change value to 'selectedCity
' and I am getting [Object object]
. Thanks!
My HTML
<select data-bind="options: Cities, optionsText: 'CityNameRu', value: selectCity">
</select>
<span data-bind="text: selectedCity"></span>
Knockout
function CityModel(data) {
var self = this;
this.CityId = ko.observable(data.CityId);
this.CityNameRu = ko.observable(data.CityNameRu);
this.CityName = ko.observable(data.CityName);
}
function ViewModel() {
var self = this;
self.Cities = ko.observableArray([]);
self.selectedCity = ko.observable();
self.selectCity = function (city) {
self.selectedCity(city.CityNameRu);
};
self.GetCities = function () {
$.ajax({
type: "GET",
url: '/FetchCities',
dataType: "json",
success: function (data) {
self.SuccessfullyRetrievedModelsFromAjax(data);
},
error: function (err) {
alert(err.status + " : " + err.statusText);
}
});
};
this.SuccessfullyRetrievedModelsFromAjax = function (models) {
ko.utils.arrayForEach(models, function (model) {
self.Cities.push(new CityModel(model));
});
};
JSON response:
[{"CityId":1,"CityName":"philadelphia","CityNameRu":"Филадельфия"},{"CityId":2,"CityName":"new-york","CityNameRu":"Нью Йорк"}
Upvotes: 2
Views: 4441
Reputation: 63729
Change a few things:
selectCity
function, just bind value
straight to the observable.The span text
is bound to an observable which holds a reference to a city, so the text
will try to render that reference as well as it can by e.g. "Object object". Instead, execute the observable to get its value, and then choose which property to show as text.
<span data-bind="text: !!selectedCity() ? selectedCity().CityNameRu : ''"></span>
Alternatively, you could utilize the with
binding. Here's how:
var data = [{"CityId":1,"CityName":"philadelphia","CityNameRu":"Филадельфия"},{"CityId":2,"CityName":"new-york","CityNameRu":"Нью Йорк"}];
var $ = { ajax: function(opts) { opts.success(data); } };
function CityModel(data) {
var self = this;
this.CityId = ko.observable(data.CityId);
this.CityNameRu = ko.observable(data.CityNameRu);
this.CityName = ko.observable(data.CityName);
}
function ViewModel() {
var self = this;
self.Cities = ko.observableArray([]);
self.selectedCity = ko.observable();
self.GetCities = function() {
$.ajax({
success: function(data) {
self.SuccessfullyRetrievedModelsFromAjax(data);
}
});
};
self.SuccessfullyRetrievedModelsFromAjax = function(models) {
ko.utils.arrayForEach(models, function(model) {
self.Cities.push(new CityModel(model));
});
};
self.GetCities();
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<select data-bind="options: Cities, optionsText: 'CityNameRu', value: selectedCity">
</select>
<div data-bind="with: selectedCity">
<span data-bind="text: CityId"></span> -
<span data-bind="text: CityName"></span> -
<span data-bind="text: CityNameRu"></span>
</div>
<hr>
Debug info: <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
Upvotes: 2
Reputation: 905
Set the whole city object as value for selectedCity
. You can also add a computed observable for retrieving text.
function ViewModel() {
var self = this;
self.Cities = ko.observableArray([]);
self.selectedCity = ko.observable();
self.selectCity = function (city) {
self.selectedCity(city);
};
self.selectedCityNameRu = ko.pureComputed(function () {
var selectedCity = self.selectedCity();
return selectedCity ? selectedCity.CityNameRu : '';
}, self);
Then in your html bind to selectedCityNameRu
<span data-bind="text: selectedCityNameRu"></span>
Upvotes: 2