3

BackboneJS アプリがあり、2 つの異なるビュー用のルーターがあります。問題は、あるビューから別のビューに移動すると正常に動作することですが、ブラウザの戻るボタンをクリックすると、ビューの 1 つが他のビューの上に追加されるだけです。(したがって、両方のビューが表示されます)。

ビューを削除したり、強制的に更新したりするにはどうすればよいですか?

  var Schedule = Parse.Object.extend({
    className: "schedule"
  });

  var Movie = Parse.Object.extend({
    className: "movie"
  });

  var ScheduleList = Parse.Collection.extend({
    model: Schedule
  });

  var schedule = new ScheduleList();
  var movie = new Movie();

  var ScheduleView = Parse.View.extend({
    initialize: function() {
          schedule.query = new Parse.Query(Schedule);
          schedule.query.ascending("date");
          schedule.query.limit('500');

          var render = this.render;

      schedule.fetch({
        success: function() {
          render(schedule.toJSON());
        }
      });
    },

    render: function(schedule) {
      console.log(schedule);
      var template = Handlebars.compile($("#schedule-item").html());
      $("#schedule-holder").html(template({shows: schedule}));
      return this;
    }
  });

  var MovieView = Parse.View.extend({
    initialize: function() {
      var query = new Parse.Query(Movie);
      query.equalTo("mId", parseInt(this.id));
      query.limit('1');

      var render = this.render;

      query.first({
        success: function(details) {
          render(details.toJSON());
        }
      });
    },

    render: function(movie) {
      var template = Handlebars.compile($("#movie-item").html());
      $("#movie-holder").html(template(movie));
      return this;
    }
  });

  var AppRouter = Parse.Router.extend({
        routes: {
            "movie/:id": "movieDetails",
            "*actions": "schedule" // Backbone will try match the route above first
        },
        movieDetails: function( id ) {
            // Note the variable in the route definition being passed in here
            var App = new MovieView({ id: id });
        },
        schedule: function( actions ){
            var App = new ScheduleView();
        }
    });

  // Instantiate the router
  var app_router = new AppRouter;

  // Start Backbone history a neccesary step for bookmarkable URL's
  Parse.history.start();
4

2 に答える 2

3

ルーターは現在のビュー (存在する場合) を追跡しremove、新しいビューを追加する前に古いビューを呼び出す必要があります。デフォルトremoveは非常に単純です。

削除する view.remove()

DOM からビューを削除するための便利な関数。を呼び出すのと同じ$(view.el).remove();です。

これにより HTML がクリアされ、イベント処理のために a がビューにdelegateEventsバインドされるため、呼び出しによってゾンビ UI イベントも防止されます。おそらく、モデルまたはコレクションにバインドされているイベント ハンドラーもバインド解除することをお勧めします。そうしないと、データ イベント ハンドラーに隠されたゾンビ ビューを取得できます。delegateelremoveremove

removeDOM から何も削除したくない場合があります。次のようなものが必要な場合があります。

remove: function() {
    this.$el.empty();
    this.undelegateEvents();
    return this;
}

ビューelはDOMに残りますが、問題は発生しません。

したがって、remove必要に応じてビューに実装を追加し、ルーターを調整して呼び出しますremove

var AppRouter = Parse.Router.extend({
    //...
    initialize: function() {
        this.view = null;
    },
    movieDetails: function( id ) {
        this._cleanUp();
        this.view = new MovieView({ id: id });
        //...
    },
    schedule: function( actions ){
        this._cleanUp();
        this.view = new ScheduleView();
        //...
    },
    _cleanUp: function() {
        if(this.view)
            this.view.remove();
        this.view = null;
    }
});
于 2012-08-29T17:09:44.550 に答える
1

この機能を制御するには、コントローラーを作成する (またはルーターをコントローラーとして使用する) またはマスター ビューを作成することをお勧めします。

次に、各ルートがトリガーされると、新しく作成されたルートを上記のコントローラーまたはマスター ビューに渡します。

var Controller = Backbone.View.extend({
      el: '#masterdiv'
      showView: function ( view ) {
         this.$el.empty().append( view.el );
      } 
});
var controller = new Controller();
var AppRouter = Parse.Router.extend({
        routes: {
            "movie/:id": "movieDetails",
            "*actions": "schedule" // Backbone will try match the route above first
        },
        movieDetails: function( id ) {
            // Note the variable in the route definition being passed in here
            var view = new MovieView({ id: id });
            controller.showView( view );
        },
        schedule: function( actions ){
            var view = new ScheduleView();
            controller.showView( view );
        }
    });
于 2012-08-29T17:05:12.703 に答える