简体   繁体   中英

Knockout mapping - JSON data

I have an api endpoint at /api/pin that returns the following JSON:

{
  "num_results": 4,
  "objects": [
    {
      "id": 1,
      "image": "http://placekitten.com/200/200/?image=9",
      "title": "Test"
    },
    {
      "id": 2,
      "image": "http://placekitten.com/200/200/?image=9",
      "title": "test"
    },
    {
      "id": 3,
      "image": "www.test.com",
      "title": "test"
    }
  ],
  "page": 1,
  "total_pages": 1
}

I want to map this into a knockout observable array and display it in my page. Here's my js file:

define(['knockout', 'text!./pins.html'], function(ko, templateMarkup) {

function Pins(params) {
    var self = this;
    self.agents  = ko.observableArray([]);

    $.getJSON('/api/pin', function(data){
        self.agents = ko.mapping.fromJS(data);
    });
 }


return { viewModel: Pins, template: templateMarkup };

});

My html:

<b data-bind="agents.num_results"> results </b>
<table>
    <tbody data-bind="foreach: agents.objects">
        <tr>
            <td data-bind="text: image"></td>
            <td data-bind="text: title"></td>
        </tr>     
    </tbody>
</table>

I get nothing rendered, other than the word "results".

I know that I can create a view model that represents the JSON data and push it into the array during the getJSON (and I've done that successfully). But I thought the whole point of the knockout mappings library was so that you didn't have to do that. I guess I'm having trouble wrapping my head around what exactly I'm doing wrong here. Seems like I must be missing something super obvious, but I'm pulling my hair out trying to figure out what's wrong.

So I figured it out. Basically I had to mock up a PinViewModel like this:

define(['knockout', 'text!./pins.html'], function(ko, templateMarkup) {

    function PinVewModel (){
      this.objects = ko.observableArray();
    }

    function Pins(params) {
        var self = this;
        self.agents   = new PinVewModel();

        $.getJSON('/api/pin', function(data){
            ko.mapping.fromJS(data, {}, self.agents);
        });
     }

   return { viewModel: Pins, template: templateMarkup };

   });

And if anyone is interested in the POST part...

  function Pin(data){
    this.image = ko.observable(data.image);
    this.title = ko.observable(data.title);
  }

  this.createPins = function(formElement){
     formPin = new Pin({image: formElement.pin_url.value, title: formElement.pin_name.value});

    $.ajax("/api/pin", {
        data: ko.toJSON(formPin),
        type: "post", contentType: "application/json",
        success: function(result) { 
            self.pins.objects.push(formPin);
        }
    });     
};

There's probably redundancy I'm doing in here, but it works and achieves the desired results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM