1


私は RequireJS と Backbone を初めて使用し、ajax (フェッチ) コードが例外として機能しない理由を理解しようとしていました。

main.js

require.config({
shim: {
    'backbone': {
        deps:['underscore', 'jquery'],
        exports: 'Backbone'
    },
    'underscore': {
        exports: '_'
    }
},
paths: {
    'jquery': 'vendor/jquery/jquery',
    'underscore': 'vendor/underscore/underscore',
    'backbone': 'vendor/backbone/backbone'
}
});
require(['views/appViews'], function(AppView) {
 new AppView();
});

AppView.js

define(['jquery', 'underscore','backbone', '../collections/appCollections'], function($, _, Backbone, AppCollections) {
    var App = Backbone.View.extend({
        initialize: function() {
            _.bindAll( this, "render" );

            this.collection = new AppCollections;

            var $this = this;

            this.collection.bind("all", this.render, this);
            var x = this.collection.fetch();
            /*
             * This was not working
            this.collection.fetch({
                success: function() {
                    $this.render();
                }
            });
            */
        },

        template: _.template( $('#tweetsTemplate').html() ),

        render: function() {
            console.log(this.collection.toJSON());
            //$(this.el).html(this.template({ tweets: this.collection.toJSON() }));
        }   
      });
      return App;
     });

AppCollections.js

define(['jquery','underscore','backbone','../models/appModels'], function($, _, Backbone, AppModel) {
 var AppCollection = Backbone.Collection.extend({

model: AppModel,

url: 'http://search.twitter.com/search.json?q=dog',

parse: function ( response, xhr ) {
        return response.results;
},
// Overwrite the sync method to pass over the Same Origin Policy
sync: function (method, model) {
    var $this = this;
    var params = _.extend({
        type: 'GET',
        dataType: 'jsonp',
        url: $this.url,
        processData: false
    }   );

    return $.ajax(params);
}

 });
 return  AppCollection;
});

アプリモデル

define(['underscore', 'backbone'], function(_, Backbone) {
var AppModel = Backbone.Model.extend({});
return AppModel;
});

問題は、コレクションがフェッチされると render メソッドが呼び出されないことです。開発者ツールにもエラーはありません。だからどこを見ればいいのかわからない。

ここに画像の説明を入力

どんなポインタでも役に立ちます。

バイラルに感謝

4

3 に答える 3

1

syncメソッドがに渡していないため、成功コールバックは呼び出されませんajax

の3番目のパラメーターsyncは、成功コールバックを含むオプションオブジェクトです。

sync: function (method, model, options) {
    var $this = this;

    var success = options.success;
    options.success = function(resp) {
      if (success) success(model, resp, options);
      model.trigger('sync', model, resp, options);
    };
    var params = _.extend({
        type: 'GET',
        dataType: 'jsonp',
        url: $this.url,
        processData: false
    }, options);

    return $.ajax(params);
}

このようにajaxして、Backbone Collectionで定義された成功コールバックを適切に呼び出し、fetch次に、fetchに渡した成功コールバックを呼び出します。

次にフェッチします。

        this.collection.fetch({
            success: function() {
                $this.render();
            }
        });

これはバックボーンソースfetchからのものです。コールバックをに渡すことがわかります。successsync

fetch: function(options) {
  options = options ? _.clone(options) : {};
  if (options.parse === void 0) options.parse = true;
  var success = options.success;
  options.success = function(collection, resp, options) {
    var method = options.update ? 'update' : 'reset';
    collection[method](resp, options);
    if (success) success(collection, resp, options);
  };
  return this.sync('read', this, options);
},
于 2013-03-01T20:52:59.137 に答える
1

バックボーンで同期メソッドを上書きすると、イベントが正しくトリガーされません。この方法で同期メソッドを上書きしてみてください

または、単に成功関数をバックボーン ソースのように見せることもできます。

success = function(resp) {
    if (success) success(model, resp, options);
    model.trigger('sync', model, resp, options);
};
于 2013-03-01T20:43:25.243 に答える
0

ポールは素晴らしい反応を示しましたが、次のことを指摘したかっただけです。

fetch の success 関数をオーバーライドして ajax 呼び出しからデータを取得しようとすると、コードに次の変更を加える必要がありました。

sync: function (method, model, options) {
    var $this = this;

    var success = options.success;
    options.success = function(resp) {
      if (success) success(resp);
      model.trigger('sync', model, resp, options);
    };
    var params = _.extend({
        type: 'GET',
        dataType: 'jsonp',
        url: $this.url,
        processData: false
    }, options);

    return $.ajax(params);
}

次の行の違いに注意してください。

if (success) success(resp);

これは、成功関数に応答を適切に渡すために必要でした。そうしないと、モデルによって上書きされていました。これで、fetch の成功関数で、データを出力できます。

var $this = this;
this.collection.fetch({
    success: function(collection, response, options){
        $this.render(response);
    }
});

これにより、ajax データ (応答) が render 関数に渡され、好きなように処理されます。もちろん、事前に任意の方法でデータを操作することもできます。

理想的には、Backbone がデフォルトで行うように、データを collection.models オブジェクトに渡すことができるようにしたいと考えています。データの解析方法と関係があると思いますが、まだわかりません。誰かが解決策を持っているなら、私はそれを聞きたいです:)

アップデート:

Backbone がそのコレクション オブジェクトを構造化する方法に忠実であるように、parse 関数をオーバーライドし、ajax 呼び出しからの JSON データを処理することができました。コードは次のとおりです。

parse: function(resp){
    var _resp = {};
    _resp.results = [];
    _.each(resp, function(model) {
        _resp.results.push(model);
    });
    return _resp.results;
}

これにより、 resultsというモデルの配列を持つ新しいオブジェクトが作成され、これがフェッチ関数に返され、各モデルの属性に直接アクセスできるようになります。

于 2013-05-02T23:36:46.977 に答える