문제

Problem Description

I wanted to ask about how to use a list Exbando Objects in knockout.js,am using Rob Conrey's Massive and all returned results are dynamic, that's fine with me it suits my needs but when it comes to sending results to knockout i just don't know what to do with it.

Goal

Access object properties like obj.Name, obj.Brand etc...

Sample Code

View:

<div data-bind="foreach: Products">
    <p>Product name: <strong data-bind="text: Name"></strong></p>
</div>

Controller:

public JsonResult GetProducts() 
{
     Products products = new Products();
     var Model = products.GetAllProducts();
     return Json(Model, JsonRequestBehavior.AllowGet);
}

The result of calling GetProducts is:

[[{"Key":"Id","Value":1},{"Key":"Name","Value":"Badass Boots"},{"Key":"Brand","Value":"Nike"},{"Key":"Description","Value":"Super cool boots that can make you fly (Not Really!)."}, etc...]]

Script File:

function ProductListViewModel() {
    // Data
    var self = this;
    self.Products = ko.observableArray([]);

    $.getJSON("/Home/GetProducts", function (data) {
        self.Products(data);
    });
}

JavaScript error on running the application:

Uncaught ReferenceError: Unable to parse bindings. Bindings value: text: Name Message: Name is not defined

Screen Shot 1:

enter image description here

Screen Shot 2:

enter image description here

도움이 되었습니까?

해결책

An ExpandoObject generally speaking is for all intents and purposes, a dictionary. When serialized as JSON here, it is treated as a dictionary and becomes a collection of key/value pairs (not all serializers behave this way, but the one you're using does). It is not an object you can access members by name, you'll have to convert it into a representation where you can (or serialize it as one in the first place).

Doing the conversion is not the worst thing in the world:

function Product(item) {
    var self = this;
    // assuming item is an array of key/value pairs
    ko.utils.arrayForEach(item, function(pair) {
        // doesn't necessarily have to be mapped as an observable
        self[pair.Key] = ko.observable(pair.Value);
    });
}

With this, you can then map the results to your array of products:

$.getJSON("/Home/GetProducts", function (data) {
    self.Products(ko.utils.arrayMap(data, function(item) {
        return new Product(item);
    }));
});

다른 팁

It looks like the problem is because you are trying to set the value of your ko.observableArray to a json array. Not sure that this will work. Typically this is how I would do it:

function ProductListViewModel() {
   // Data
   var self = this;
   self.Products = ko.observableArray([]);

   $.getJSON("/Home/GetProducts", function (data) {
       ko.utils.arrayForEach(data, function(item) {
           self.Products.push({
               Name : item.Name
           });
       });
   });

}

Use knockout's arrayForEach function to iterate through your json array, and push each object into your observableArray.

As in your JSON I see the sequence of Key and Value, so you have to specify the filed name which knockout has to query for to get the relative value and put it on the screen.

So change <strong data-bind="text: Name"> to <strong data-bind="text: Key"> and this should work for you.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top