Domanda

Here's what I have mocked out of my MVC code:

$(function(){

    var ViewModel = function(){
      this.items = ko.observableArray(null);
      this.isLoading = ko.observable(true);  
    };

    var data = [{"CreatedAt":"2013-12-29T22:00:20","Intro":"","Body":"","Title":"Test Item","Url":"/news-items/test-item/"},{"CreatedAt":"2013-12-29T21:13:34","Intro":"","Body":"","Title":"Test 1","Url":"/news-items/test-1/"},{"CreatedAt":"2013-12-29T16:03:56","Intro":"","Body":"<p>In the spirit of Christmas we are holding a Christmas photo competition for all members to enter. Prizes will be given to the best Christmas themed photo and the funniest photo.&nbsp; To enter, simply email your photo to: competition@bernese.org.nz. Your entry will be uploaded onto the club's Facebook page where all members can then vote by 'liking' their favourite photo.</p>\n<p>Entries close on the 20th of December and voting will be open until the 5th of January. The winning photo's will be displayed on the website.</p>","Title":"Christmas 2013 Photo Competition","Url":"/news-items/christmas-2013-photo-competition/"}];
  var vm = new ViewModel();
  ko.applyBindings(vm);
  vm.items(test);
  vm.isLoading(false);
})

I have mocked it from my MVC code, but the data object is basically what was returned from my controller. Knockout mapping is not working in this case and I suspect it's the way my data is returned. Is this a valid way, or do I need to wrap it in a DTO of sorts, e.g.: { items: [{item1:'...'},{item2:'...'}]}?

Thanks.

EDIT: My mistake, I already defined items as observableArray. I use it this way so as soon as the page loads the loader gif is displayed. I have done it this way before, the only difference this time being the format of the json returned.

ADDED: Here's the example

È stato utile?

Soluzione 2

The ko.mapping.fromJS(data) returns a ko.observableArray if the data parameter is already an array.

So you need to unwrap the returned ko.observableArray before assigning it:

var vm = new ViewModel();
ko.applyBindings(vm);
var test = ko.mapping.fromJS(data);
vm.items(test()); // you need to write `test()` to get the underlaying array.

Or you can directly fill in your already declared ko.observableArray with writing:

var vm = new ViewModel();
ko.applyBindings(vm);
ko.mapping.fromJS(data, {} /* mapping options */, vm.items);

Here is your updated JSFiddle.

Altri suggerimenti

I don't know if this is the only problem, but

this.items = ko.observable(null);  

should be

this.items = ko.observableArray();

But I probably do the whole thing more like

$(function(){
    var ViewModel = function(items){
        this.items = ko.observableArray(items);  
    };

    var data = [...];
    var vm = new ViewModel(data);
})

UPDATE: Here is a fully working jsfiddle

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top