0

いくつかのことを追跡するために新しい Tracker.Dependency を使用していますが、以下のコードの自動実行が無限に実行されます。なにが問題ですか?以下のコードは、getSong と getSongId を分離して、dep だけでなく、dep と dep2 に依存するようにすれば問題ありません。

SongManager = {
  dep: new Tracker.Dependency,
  dep2: new Tracker.Dependency,
  init: function(songId) {
    var self = this;
    this.setSongId(songId);
    Meteor.subscribe('song', songId);
    Tracker.autorun(function(){
      var songs = self.getSongCursor().fetch();
      if (songs.length > 0) {
        self.song = songs[0];
        self.dep.changed();
      }
    })
  },
  getSongCursor: function(){
    return Songs.find({_id: this.getSongId()});
  },
  getSong: function(){
    this.dep.depend();
    return this.song;
  },
  getSongId: function(){
    this.dep2.depend();
    return this.songId;
  },
  setSongId: function(arg){
    this.songId = arg;
    this.dep2.changed();
  },
};
4

1 に答える 1

3

問題は、循環依存関係を作成していることです。ReactiveVar低レベルの依存関係 API を使用するよりも、これを使用することをお勧めします。

meteor add reactive-var

次に、これを行うことができます:

SongManager = {

  song: new ReactiveVar(),

  songId: new ReactiveVar(),

  init: function(songId) {
    this.songId.set(songId);
    this.computation = Tracker.autorun(_.bind(this.update, this));
  },

  update: function() {
    var songId = this.songId.get();
    Meteor.subscribe('song', songId);
    this.song.set(Songs.findOne(songId));
  },

  stop: function() {
    this.computation.stop();
  }
};

SongManager.init(oldSongId);
SongManager.songId.set(newSongId);

// After enough time has passed for the subscription to update and tracker to flush:
var currentSong = SongManager.song.get();
console.log(currentSong._id === newSongId); // true

また、自動実行計算を停止する方法を追加したので、不要になったときにバックグラウンドで実行し続けないようにしました。サブスクリプションは自動実行内で実行されるため、songId変更時に自動的に停止および再開されることに注意してください。update 関数は実際には 2 回実行されますが、Meteor は 2 つの同一のサブスクリプション要求を送信しないことを認識しています。

于 2014-12-02T01:04:56.557 に答える