最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to initialize knockoutjs view model with .ajax data - Stack Overflow

programmeradmin0浏览0评论

The following code works great with a hardcoded array (initialData1), however I need to use jquery .ajax (initialData) to initialize the model and when I do the model shows empty:

    $(function () {

        function wiTemplateInit(winame, description) {
            this.WIName = winame
            this.WIDescription = description
        }

        var initialData = new Array;

        var initialData1 = [
            { WIName: "WI1", WIDescription: "WIDescription1" },
            { WIName: "WI1", WIDescription: "WIDescription1" },
            { WIName: "WI1", WIDescription: "WIDescription1" },
        ];
        console.log('gridrows:', initialData1);

        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            data: "{UserKey: '10'}",
            url: "WIWeb.asmx/GetTemplates",
            success: function (data) {
                for (var i = 0; i < data.d.length; i++) {
                    initialData.push(new wiTemplateInit(data.d[i].WiName,data.d[i].Description));
                }
                //console.log('gridrows:', initialData);
                console.log('gridrows:', initialData);
            }
        });

        var viewModel = function (iData) {   
            this.wiTemplates = ko.observableArray(iData);

        };

        ko.applyBindings(new viewModel(initialData));

    });

I have been trying to work from the examples on the knockoutjs website, however most all the examples show hardcoded data being passed to the view model.

The following code works great with a hardcoded array (initialData1), however I need to use jquery .ajax (initialData) to initialize the model and when I do the model shows empty:

    $(function () {

        function wiTemplateInit(winame, description) {
            this.WIName = winame
            this.WIDescription = description
        }

        var initialData = new Array;

        var initialData1 = [
            { WIName: "WI1", WIDescription: "WIDescription1" },
            { WIName: "WI1", WIDescription: "WIDescription1" },
            { WIName: "WI1", WIDescription: "WIDescription1" },
        ];
        console.log('gridrows:', initialData1);

        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            data: "{UserKey: '10'}",
            url: "WIWeb.asmx/GetTemplates",
            success: function (data) {
                for (var i = 0; i < data.d.length; i++) {
                    initialData.push(new wiTemplateInit(data.d[i].WiName,data.d[i].Description));
                }
                //console.log('gridrows:', initialData);
                console.log('gridrows:', initialData);
            }
        });

        var viewModel = function (iData) {   
            this.wiTemplates = ko.observableArray(iData);

        };

        ko.applyBindings(new viewModel(initialData));

    });

I have been trying to work from the examples on the knockoutjs website, however most all the examples show hardcoded data being passed to the view model.

Share Improve this question asked Jan 13, 2012 at 20:27 Peter Rackauskas Jr.Peter Rackauskas Jr. 111 silver badge2 bronze badges 4
  • Have you debugged the network transmission to see what es back? Check to see if anything es back. If it does, what shape is the data? Is it the same as your hard coded date? Is there an error? – John Papa Commented Jan 13, 2012 at 20:37
  • "however most all the examples show hardcoded data being passed to the view model". Are you sure about that? – kamranicus Commented Jan 13, 2012 at 20:52
  • John-I debugged and checked the array with console.log, the data is getting to the client. Both arrays are same syntax with no errors. – Peter Rackauskas Jr. Commented Jan 13, 2012 at 21:45
  • sub- been there, I just didn't find those examples useful since they are not shown with any UI or model flow plexity. – Peter Rackauskas Jr. Commented Jan 13, 2012 at 21:49
Add a ment  | 

2 Answers 2

Reset to default 7

make sure your "WIWeb.asmx/GetTemplates" returns json array of objects with exact structure {WIName : '',WIDescription :''} and try using something like this

    function wiTemplateInit(winame, description)
    {
        var self = this;
        self.WIName = winame;
        self.WIDescription = description;
    }

    function ViewModel()
    {
        var self = this;
        self.wiTemplates = ko.observableArray();

        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            data: "{UserKey: '10'}",
            url: "WIWeb.asmx/GetTemplates",
            success: function (data)
            {
                var mappedTemplates = $.map(allData, function (item) { return new wiTemplateInit(item.WiName, item.Description) });
                self.wiTemplates(mappedTemplates);

            }
        });
    }

    var vm = new ViewModel();

    ko.applyBindings(vm);

If you show us your browser log we can say more about your problem ( Especially post and response ). I prepared you a simple example to show how you can load data with ajax , bind template , manipulate them with actions and save it.

Hope this'll help to fix your issue : http://jsfiddle/gurkavcu/KbrHX/

Summary :

 // This is our item model 
function Item(id, name) {
   this.id = ko.observable(id);
   this.name = ko.observable(name);
}

// Initial Data . This will send to server and echo back us again
var data = [new Item(1, 'One'),
            new Item(2, 'Two'),
            new Item(3, 'Three'),
            new Item(4, 'Four'),
            new Item(5, 'Five')]

// This is a sub model. You can encapsulate your items in this and write actions in it
var ListModel = function() {    

   var self = this;    
   this.items  = ko.observableArray();
   this.remove = function(data, parent) {
        self.items.remove(data);
   };
   this.add    = function() {
        self.items.push(new Item(6, "Six"));
   };
   this.test   = function(data, e) {
       console.log(data);
       console.log(data.name());
   };
   this.save   = function() {        
       console.log(ko.mapping.toJSON(self.items));
   };   
}

// Here our viewModel only contains an empty listModel
function ViewModel() {
    this.listModel = new ListModel();
};

var viewModel = new ViewModel();

$(function() {
    $.post("/echo/json/", {
        // Data send to server and echo back
        json: $.toJSON(ko.mapping.toJS(data))
    }, function(data) {

    // Used mapping plugin to bind server result into listModel
    // I suspect that your server result may contain JSON string then 
    // just change your code into this
    // viewModel.listModel.items = ko.mapping.fromJSON(data); 

    viewModel.listModel.items = ko.mapping.fromJS(data);

    ko.applyBindings(viewModel);
});
})
发布评论

评论列表(0)

  1. 暂无评论