5

私は、Python の CherryPy フレームワークで書かれた安らかな API を搭載した Web アプリケーションに取り組んでいます。jQuery とサーバー側のテンプレートを組み合わせてユーザー インターフェイスを書き始めましたが、jQuery が手に負えなくなってきたため、最終的に Backbone.js に切り替えました。

残念ながら、モデルをサーバーと同期させるのに問題があります。私のコードの簡単な例を次に示します。

$(function() {
    var User = Backbone.Model.extend({
        defaults: {
            id: null,
            username: null,
            token: null,
            token_expires: null,
            created: null
        },

        url: function() {
            return '/api/users';
        },

        parse: function(response, options) {
            console.log(response.id);
            console.log(response.username);
            console.log(response.token);
            console.log(response.created);
            return response;
        }
    });

    var u = new User();
    u.save({'username':'asdf', 'token':'asdf'}, {
        wait: true,
        success: function(model, response) {
            console.log(model.get('id'));
            console.log(model.get('username'));
            console.log(model.get('token'));
            console.log(model.get('created'));
        }
    });
});

お分かりのように、ここでの目的は、新しいユーザーをサービスに登録することです。を呼び出すとu.save();、Backbone は実際に POST 要求をサーバーに送信します。関連するビットは次のとおりです。

リクエスト:

Request URL: http://localhost:8080/api/users
Request Method: POST
Request Body: {"username":"asdf","token":"asdf","id":null,"token_expires":null,"created":null}

応答:

Status Code: HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 109
Response Body: {"username": "asdf", "created": "2013-02-07T13:11:09.811507", "token": null, "id": 14, "token_expires": null}

ご覧のとおり、サーバーはリクエストを正常に処理し、idと の値を返しますcreated。しかし、何らかの理由で、コードが を呼び出すconsole.log(u.id);と を取得nullし、コードが を呼び出すconsole.log(u.created);と を取得しundefinedます。

tl;dr : を呼び出した後、Backbone.js がオブジェクトへの変更を保持しないのはなぜsave()ですか?

編集:コールバック で get 関数を使用してモデル プロパティにアクセスできるように、上記のコードを修正しましたsuccess。これにより、元のコードの同時実行の問題が解決されます。

parseまた、モデルの関数にコンソール ロギングを追加しました。奇妙なことに、これらのそれぞれはundefined... Backbone.js が応答 JSON の解析に失敗しているということですか?

編集 2: 数日前、問題は実際には、HTTP 基本認証を有効にするためにすべての要求に追加していたカスタム ヘッダーであることがわかりました。詳細については、この回答を参照してください。

4

4 に答える 4

3

私は問題を理解しましたが、なぜそれが問題なのかを説明するにはまだ途方に暮れています. 私が構築している Web アプリには、すべての要求で HTTP 基本認証ヘッダーを渡す必要がある認証プロセスがあります。

これを Backbone で機能させるために、Backbone.sync 関数を上書きし、1398 行を変更してヘッダーを追加しました。

元のコード:

var params = {type: type, dataType: 'json'};

変更されたコード:

var params = {
    type: type,
    dataType: 'json',
    headers: {
        'Authorization': getAuthHash()
    }
};

関数 getAuthHash() は、適切な認証情報を表す Base64 文字列を返すだけです。

何らかの理由で、このヘッダーを追加すると、同期/保存機能が失敗します。私がそれを取り出すと、すべてが期待どおりに機能します。

報奨金はまだ公開されています。その理由を説明し、問題の解決策を提供できる人には喜んで報奨金を贈ります.

編集:

問題は、リクエストにヘッダーを追加する方法にあったようです。HTTP Basic Auth ヘッダーを正しく追加することで、この問題を解決する小さな JavaScript ライブラリが Github で入手できます。

于 2013-02-21T13:20:03.100 に答える
3

このコード:

u.save();
console.log(u.id);
console.log(u.username);
console.log(u.token);
console.log(u.created);

すぐに実行されます...その後、実行するものは何もなく、キューに入れられた ajax リクエストが開始されます。少し遅れて応答が返され、その時点でのみ値が変更されます。

また、これらのプロパティはオブジェクトに直接ではないようですが、保存の非同期処理は、そのコードを修正しても期待される結果が得られないという点で依然として保持されていますconsole.log(u.get("id"))

于 2013-02-07T13:34:56.720 に答える
2

私はあなたのコードをテストしました、それは私にとってはうまくいきます。

ここでデモを参照してください。jsfiddle.net/yxkUD/

于 2013-02-27T05:54:58.537 に答える
1

カスタム beforeSend メソッドを ajax リクエストに追加して、カスタム ヘッダーを追加してみてください。

例: https://github.com/documentcloud/backbone/blob/master/backbone.js#L1424

于 2013-02-25T14:45:16.113 に答える