1

私の最終的な目標は、JSON データを にul#tweets、それぞれ個別の隠しリスト アイテムとして追加することです。その後、時間の経過とともに 1 つずつ画面に表示/表示され、ul#tweetsリストから削除されます。

非表示のアイテムの数が一定量を下回ったら、JSON データを再度追加したいと考えています。この場合、アイテムが重複する心配はありません。

5秒ごとにJSONデータをリストに追加するように、タイムアウトのある関数を作成してテストをセットアップしようとしました。

ただし、私のアプリはページロード時に初期データを正常にロードしますが、実行する関数を作成すると機能し$(document).ready({})ません。

ただし、ページの読み込み後にコンソールに JSON データを手動で追加できることはわかっています (関数または doc.ready でラップせずに以下のコードと同じ)。

助けてくれてありがとう!

関数:

$(document).ready(function(){
   updateTweets = function() {

    newTweets = new Tweets();
    newTweets.fetch();

    newTweets.each( function(tweet) {

      console.log('test'); // this doesn't work
      view = new TweetView({ model:tweet });
      $('#tweets').append(view.render().el);
    });

    setTimeout(updateTweets, 5000);
  };
  updateTweets();

});


これが私のコードです

// MODEL
window.Tweet = Backbone.Model.extend({});

// COLLECTION
window.Tweets = Backbone.Collection.extend({ model: Tweet, url: '/tweets' });

// SET GLOBAL VARIABLE FOR NEW TWEETS COLLECTION
window.tweetList = new Tweets();

$(document).ready(function() {

// MODEL VIEW
window.TweetView = Backbone.View.extend({
    tagName: 'li',
    className: 'tweet',

    initialize: function() {
        _.bindAll(this, 'render');
        this.model.bind('change', this.render);
        this.template = _.template($('#tweet-template').html());
    },

    render: function(){
        var renderedTweets = this.template(this.model.toJSON());
        $(this.el).html(renderedTweets);

        return this;
    }
});

// COLLECTION VIEW
window.TweetListView = Backbone.View.extend({

  template: _.template($('#tweet-list-template').html()),

  initialize: function() {

    _.bindAll(this, 'render');
    this.collection.bind('reset', this.render);

  },

  render: function() {
    var $tweets,
    collection = this.collection;

    $(this.el).html(this.template({}));
    $tweets = this.$('#tweets');
    collection.each(function(tweet){
      var view = new TweetView({
        model: tweet,
        collection: collection
      });
      $tweets.append(view.render().el);
    });
    return this;
  }
});

// ROUTER
window.TweetListDisplay = Backbone.Router.extend({
  routes: {
    '': 'home'
  },
  initialize: function(){
    this.tweetListView = new TweetListView({
      collection: window.tweetList
    });
  },
  home: function() {
    var $container = $('#container');
    $container.empty();
    $container.append(this.tweetListView.render().el);
  },
});

// DECLARE AND START APP
window.app = new TweetListDisplay();
Backbone.history.start();

}); // close $(document).ready({});
4

2 に答える 2

1

ここでフェッチを呼び出します

newTweets.fetch();

そして、コレクションが入力されたかのようにコレクションの処理を開始した直後に、ここに

newTweets.each( function(tweet) {

  console.log('test'); // this doesn't work
  view = new TweetView({ model:tweet });
  $('#tweets').append(view.render().el);
});

fetchfetchはASYNCHRONOUS操作です。つまり、起動した後、によって起動されたajax呼び出しが戻ったかどうかに関係なく、プログラムの残りの部分は直後に実行を継続します。したがって、コレクションの処理を開始しても、フェッチはまだ返されておらず、コレクションはまだ空です。

この状況を修正する方法は2つあります。processCollectionコレクションに対して必要な機能を正確に実行する関数を作成することから始めましょう。

var processCollection = function () {
  newTweets.each( function(tweet) {

    console.log('test'); // this doesn't work
    view = new TweetView({ model:tweet });
    $('#tweets').append(view.render().el);
  });
};

1コールバック関数(私はこれらが好きではありません)

newTweets.fetch(success: processCollection);

processCollectionフェッチが成功した直後に呼び出されます。

2イベントにバインドします(私はこれが好きです)

newTweets.on('reset', processCollection);
newTweets.fetch();

フェッチが正常に戻ると、コレクションにデータが入力され、reset-eventが発生します。これでコレクションにデータが入力されることがわかっているので、これは処理イベントを結び付けるのに適した場所です。また、コールバックよりもイベントのスコープの問題がわずかに少ないことがわかりました。

お役に立てれば!

于 2012-09-11T10:05:00.620 に答える
0

あなたは電話できません。

 newTweets.fetch();

そして、すぐに使用できるかのようにコレクションの処理を開始します..時間がかかります.フェッチ呼び出しは非同期です..コンソールで機能する理由は、コンソールの出力を準備するのに時間がかかるためです..フェッチは行います本当に終わり..

次のように、フェッチの成功のコールバックを提供する必要があります。

 newTweets.fetch({success: function(){//process collection}});
于 2012-09-11T09:53:02.547 に答える