Knockoutjs object allocation problem

I study knockouts and have some problems. I have an ASP.NET MVC page with a method that returns a list of three Car objects, this is JSON. I, than to compare it with select in the HTML form, and I want to display the cost of the selected car when changing the choice. The problem is that the name of the car is visible until the price is ("Mercedes-Benz costs"). What could it be? Thank you in advance! Controller:

 public class Car { public string Make { get; set; } public decimal Price { get; set; } } public JsonResult GetCars() { List<Car> cars = new List<Car>(); cars.Add(new Car { Make = "Mercedes-Benz", Price = 103000 }); cars.Add(new Car { Make = "Toyota", Price = 37000 }); cars.Add(new Car { Make = "Huyndai", Price = 17000 }); return Json(cars, JsonRequestBehavior.AllowGet); } 

And view with Javascript code:

 <head> <script type="text/javascript" src="~/Scripts/jquery-2.0.3.min.js"></script> <script type="text/javascript" src="~/Scripts/knockout-3.0.0.js"></script> <script type="text/javascript"> $(document).ready(function () { function Car(data) { this.Make = ko.observable(data.Make); this.Price = ko.observable(data.Price); } function CarsViewModel() { var self = this; //Data self.someOptions = ko.observableArray([]); self.myOption = ko.observable(); //Operations self.initData = function () { $.get('/Home/GetCars', function (data) { var mappedCars = $.map(data, function (item) { return new Car(item) }); self.someOptions(mappedCars); }); } } ko.applyBindings(new CarsViewModel()); }); </script> </head> <body> <div> <button data-bind="click: initData">Load data</button> <h4>Preview</h4> <p> <select data-bind="options: someOptions, optionsText: 'Make', value: myOption"></select><br /> A <span data-bind="text: myOption().Make"></span> costs <span data-bind="text: myOption().Price"></span>. </p> </div> </body> 
+6
source share
1 answer

If you check the browser JavaScript console, you will see the following error:

Uncaught TypeError: cannot handle the binding: text: function () {return myOption (). Make} Message: Cannot read the property "Make" undefined

You get this error because when your page is loaded, your myOption empty, so it does not have Make and Price properties. Therefore, KO cannot bind data-bind="text: myOption().Make" and stops processing further bindings.

After calling initData , you now have something in myOption , but all the bindings after data-bind="text: myOption().Make" will no longer work.

To solve this problem, there are several ways:

  • using default value in myOption
  • check the null value in your bindings with data-bind="text: myOption() && myOption().Make"
  • or use with binding

Here is an example with binding:

 <!-- ko with: myOption --> A <span data-bind="text: Make"></span> costs <span data-bind="text: Price"></span>. <!-- /ko --> 

JSFiddle demo.

+15
source

Source: https://habr.com/ru/post/957104/


All Articles