使用Knockout.js发出绑定JSONP数据

时间:2013-01-30 22:29:29

标签: asp.net web knockout.js asp.net-web-api knockout-2.0

我正在开发一个涉及跨域调用的Web项目,我决定使用Knockout.js和ASP.NET Web Api。我在VS 2012中使用了单页应用程序模板,并按原样实现了Knockout类。当我从同一个域进行JSON调用时,该页面运行良好,但是当我尝试从远程服务器使用JSONP时,敲除似乎不会绑定数据。我可以在进行JSONP调用时看到从远程接收的JSON数据,但是knockout无法绑定数据。

这是我的JavaScript ViewModel类:

window.storyApp.storyListViewModel = (function (ko, datacontext) {
    //Data
    var self = this;
    self.storyLists = ko.observableArray();
    self.selectedStory = ko.observable();   
    self.error = ko.observable();

    //Operations
    //Load initial state from the server, convert it to Story instances, then populate self

    datacontext.getStoryLists(storyLists, error); // load update stories      

    self.selectStory = function (s) {
        selectedStory(s); $("#showStoryItem").click(); window.scrollTo(0, 0);
        storyItem = s;        
    }
    //append id to the hash for navigating to anchor tag
    self.backToStory = function () {        
        window.location.hash = storyItem.id;       
    }

    self.loadStories = function () {
        datacontext.getStoryLists(storyLists, error); // load update stories
    }

    return {
        storyLists: self.storyLists,
        error: self.error,        
        selectStory: self.selectStory
    };
})(ko, storyApp.datacontext);

// Initiate the Knockout bindings
ko.applyBindings(window.storyApp.storyListViewModel);

我的DataContext类如下:

window.storyApp = window.storyApp || {};

window.storyApp.datacontext = (function (ko) {

    var datacontext = {
        getStoryLists: getStoryLists
    };

    return datacontext;

    function getStoryLists(storyListsObservable, errorObservable) {
        return ajaxRequest("get", storyListUrl())
            .done(getSucceeded)
            .fail(getFailed);

        function getSucceeded(data) {
            var mappedStoryLists = $.map(data, function (list) { return new createStoryList(list); });
            storyListsObservable(mappedStoryLists);
        }

        function getFailed() {
            errorObservable("Error retrieving stories lists.");
        }

        function createStoryList(data) {
            return new datacontext.StoryList(data); // TodoList is injected by model.js
        }
    }

    // Private
    function clearErrorMessage(entity) {
        entity.ErrorMessage(null);
    }

    function ajaxRequest(type, url, data) { // Ajax helper
        var options = {
            dataType: "JSONP",
            contentType: "application/json",
            cache: false,
            type: type,
            data: ko.toJSON(data)
        };
        return $.ajax(url, options);
    }

    // routes
    function storyListUrl(id) {
        return "http://secure.regis.edu/insite_webapi/api/story/" + (id || "");
    }
})(ko);

此页面:http://insite.regis.edu/insite/index.html对secure.regis.edu进行跨域调用,但无效。但是,使用JSON调用的secure.regis.eduinsite / index.html上的同一页面工作正常。

我做错了什么?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

感谢您提供的帮助。

我设法通过将WebApiContrib.Formatting.Jsonp类添加到我的WebApi项目来解决问题,如https://github.com/WebApiContrib/WebApiContrib.Formatting.Jsonp中所述,并对我的jQuery Ajax助手类稍作修改,如下所示:

function ajaxRequest(type, url, data, callbackWrapper) { // Ajax helper
    var options = {
        dataType: "jsonp",
        crossDomain : true,
        type: type,
        jsonp: "callback",
        jsonpCallback: callbackWrapper,
        data: ko.toJSON(data)
    };   

    return $.ajax(url, options);
}

一切都充满了魅力。

答案 1 :(得分:1)

我建议如下:

创建一个简化的示例(没有Knockout),它只是通过简单的警报式成功和错误回调来进行AJAX调用。确认它在跨域案件中引发了错误。

检查以下链接:parsererror after jQuery.ajax request with jsonp content type。如果这不足以告诉您,请搜索Web(和StackOverflow)以获取有关jQuery JSONP解析器和回调的信息。

如果你仍然被困,并且你已经完成#1并看到了我期望你会看到的内容,请用你的简化示例重写这篇文章,并删除对Knockout的任何引用(标题,标签)。我知道Knockout,但我不认识JSONP,知道JSONP的人似乎并没有触及这个,所以我认为这个问题正在触及错误的观众。更改标题和标签以强调JSONP /跨域方面可以为您提供所需的帮助。