0

当使用backbone.js 和web api 控制器时,这是一个两阶段的问题。

我有一个简单的 web api 控制器,它返回一个 JSON 字符串,在提琴手中,结果如下所示:

{
    "$type": "MvcApplication.Models.Article, MvcApplication",
    "Id": "1",
    "Heading":"The heading"
}

我使用以下代码从我的 web api 获取用户

var user = new Usermodel({ id: "1" });

user.fetch({
    success: function (u) {
        console.log(u.toJSON());
    }
});

现在我的主干用户对象看起来像这样

{
    id: "1",
    {
        "$type": "MvcApplication.Models.Article, MvcApplication",
        "Id": "1",
        "Heading": "The heading"
    }
}

当我尝试将此骨干模型对象绑定到我的视图模板时,看起来像这样

<form>
    <input type="text" value="<%=Heading%>" />
    <input type="submit" value="Save" />
</form>

我明白了,标题未定义的,但是当我使用 id 时它绑定得很好?似乎下划线不喜欢主干模型对象,只想要一个普通的 JSON 对象,就像我从我的 web api 获得的对象一样?

第二个问题是,当我将带有user.save({ Heading: "my new heading });有效负载的模型保存到我的 web api主干模型是完全错误的,因为我的 api 期望将这样的用户对象发送到服务器:

{
    "$type": "MvcApplication.Models.Article, MvcApplication",
    "Id": "1",
    "Heading":"The heading"
}

不是包裹在里面的真实物体的主干模型。是否有可能解决这样下划线可以处理骨干模型并告诉骨干只发送我的端点期望的有效负载?

4

3 回答 3

1

您可以按照以下步骤解决问题:

除了使用 fiddler 来检查您的响应之外,请查看 Chrome 开发者工具的网络选项卡上的响应。如果响应看起来不像这样,那么您的 web api 没有返回有效的 json 响应,问题很可能在您的 web api 中。您需要获取/提供有关您的 Web api 的更多信息来解决问题。验证响应是否如下所示:

在此处输入图像描述

验证来自web api的响应正确后,查看我修改的以下jsfiddle:

http://jsfiddle.net/J83aU/23/

参考我提供的示例修复您的客户端代码。

正确实例化 Backbone 对象。

从服务器收到响应后,在正确的步骤调用 view.render 函数。

在创建依赖于“view.el”属性的视图之前,请确保实际呈现主要内容 div。

使用字符串而不是 jQuery 对象正确声明“view.el”属性。

使用开发 Backbone 和下划线来启用调试,这是学习使用 Backbone 等开源框架时的一个重要概念。

使用 jsfiddle 的 echo/json api 模拟有效的 ajax json 响应,完全按照步骤 1 中的描述。

您提交的以下json示例甚至不是有效的json,如果您使用有效的json示例更新您的问题,解决问题会更容易。Backbone 不太可能创建此非 json 结构,更有可能是您在此处错误地提交了它。

{
    id: "1",
    {
        "$type": "MvcApplication.Models.Article, MvcApplication",
        "Id": "1",
        "Heading": "The heading"
    }
}

最后,尝试为调用 model.save() 时出现的问题提供 http 标头的屏幕截图或其他内容。

阅读 model.save() 的 Backbone 文档,并确保您按照提供的示例执行所有操作。

您可以通过使用 ajax 选项将属性强制转换为 POST 参数来解决 Backbone 的时髦保存功能:

$.fn.serializeObject = function(){
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

var saveView = Backbone.View.extend({
    events:{
        'click #saveSubmitButton':'submit'
    },
    submit:function (event) {

        event.preventDefault();
        var view = this, 
            attributes = $('#saveForm').serializeObject();

        this.model.save(attributes, {
            data:attributes,
            processData:true,
            success:function (model) {
                //....
            }
        });
    },
    render:function () {
        //.......
    }
});
于 2013-03-25T17:22:19.060 回答
0

The attributes property of your model should be unaltered. Send those to your template call:

var MyModel = Backbone.Model.extend();
var newModel = new MyModel({
    "$type": "MvcApplication.Models.Article, MvcApplication",
    "Heading":"The heading"
});
var html = _.template(templateVar, newModel.attributes);

In your templateVar, which is your templated markup, you should be able to reference $type and Heading directly.

于 2013-03-17T17:08:17.590 回答
0

如果您通过 Firebug 之类的调试器查看 jsFiddle,您会发现构建模型 URL 的方式不可行,因为正斜杠已被编码。您可以尝试将您的模型声明修改为:

var Usermodel = Backbone.Model.extend({
    url: function () {
        return '/api/page/articles/' + this.get('id');
    }    
});

var user = new Usermodel({
    id: '85'
});

看看你是否仍然得到相同的 JSON。基本上,如果您没有 Backbone.sync 覆盖,则您正在使用内置检索,因为它不应该产生无效的 JSON。

于 2013-03-17T18:44:43.260 回答