【问题标题】:increment issue with backbone骨干的增量问题
【发布时间】:2013-10-28 19:10:24
【问题描述】:

我找不到任何提到我的问题的东西,我正在使用我在主干中的路由器文件通过使用下一个和上一个按钮根据当前页面 ID 导航到不同的页面。但是,当我单击下一个或上一个时,它可以正常工作,但是第二次单击该按钮时,该函数被调用两次而不是一次,然后如果我再次单击它,它似乎被调用了两次以上它似乎发狂了。

这是我的路由器文件:

define([
    'jquery',
    'underscore',
    'backbone',
    'views/page',
    'models/search',
    'views/search',
    'text!templates/search.html',
    'models/song',
    'text!templates/song.html'


], function($, _, Backbone, PageV, SearchM, SearchV, SearchT, SongM, SongT) { 
    var vent = _.extend({}, Backbone.Events);
    var AppRouter = Backbone.Router.extend ({
        routes: {
            'page/:id': 'showPage',
            'search': 'showView' ///:page
        }
    });

    var initialize = function () {
        var app_router
        app_router = new AppRouter;


        console.log('router file hit');

        app_router.on('route:showPage', function (id) {
            console.log('page rendered');
            var songies, collected, songM;
            songM = new SongM();
            songM.localStorage = new Backbone.LocalStorage("music");
            songM.localStorage.findAll().forEach(function (i) {
                collected = i;
            });
            var songPages = Math.ceil(collected.music.length / 25); //10 pages
            var start = id * 25;
            var songies = collected.music.splice(start, 25); 
            var titles = {
                week: collected.week,
                year: collected.year,
                channel: collected. channel
            };
            var page = new PageV({model: songM, collection: songies, vent: vent, titles: titles});
            page.render(id);
            vent.on('next', advance);
            vent.on('previous', moveBack);
            var currentId = parseInt(id);
   //PROBLEM OCCURS TO THE BOTTOM TWO FUNCTIONS, and they are triggered by the vent.on above.

            function moveBack () {
                console.log('here is the current ID');
                var newPage = 'page/' + (currentId - 1);

                if(currentId <= songPages && currentId > 0 ) {
                    app_router.navigate(newPage, true);
                } else {
                    app_router.navigate('search', true);
                }
            }
            function advance () {
                console.log('here is the current ID');
                var newPage = 'page/' + (currentId + 1);
                console.log(currentId);
                console.log(songPages);
                console.log(newPage);
                if(currentId < songPages && currentId >=0 ) {
                    app_router.navigate(newPage, true);
                } else {
                    app_router.navigate('search', true);

                }

            }

        });

        app_router.on('route:showView', function () {
            console.log('search page loaded');
            var searchM = new SearchM();
            var search = new SearchV({model: searchM, vent: vent}); //
            search.render();
            vent.on('nextPage', printCons);
            function printCons () {
                console.log('changing pages');
                app_router.navigate('page/0', true);
            }; 


        });

        Backbone.history.start();

    };

    return {
        initialize: initialize
    };
});

这是带有页面视图的页面:

define([
  'jquery',
  'underscore',
  'backbone',
  'models/song',
  'collections/songs',
  'views/song',
  'text!templates/page.html',
  'text!templates/song.html'

], function($, _, Backbone, Song, Songs, SongV, PageT, SongT){ 

  var Page = Backbone.View.extend({

    el: $("#Sirius"),
    events: { 
      "click .prev": "previous",
      "click .next": "next"
    },
    previous: function () {
       this.options.vent.trigger('previous');
    },
    next: function () {
       this.options.vent.trigger('next');
    },
    render: function () {
      var headings = this.options.titles; 
      var info = {
        week: headings.week,
        channel: headings.channel,
        year: headings.year
      }
      var pagetemp = _.template( PageT, info);
      this.$el.html( pagetemp );
      var songColl = this.collection;
      var songV = new SongV({collection: songColl});
      songV.render();

    }


  });
    return Page;
});

我能想到的唯一问题是它以某种方式记住过去的实例并在它们两个上调用函数......否则我不知道为什么它被调用两次......因为如果我刷新页面该 id 然后单击上一个或下一个它不会将其增加两次...所以它必须在内存中或不确定如何绕过它...

【问题讨论】:

    标签: javascript jquery backbone.js


    【解决方案1】:

    问题在于您的 app_router.on 事件处理程序中的以下事件处理程序绑定:

    vent.on('next', advance);
    vent.on('previous', moveBack);
    

    每次显示新路由时,都会再次将这些函数绑定到事件聚合器。您应该将这两个绑定移到初始化函数之外,这样您就不会多次绑定它。

    另一个快速解决方法是,如果由于某种原因将这些绑定移到外部会破坏功能,则取消绑定之前的绑定,然后再次绑定事件处理程序:

    vent.off('next');
    vent.on('next', advance);
    vent.off('previous');
    vent.on('previous', moveBack);
    

    有关此问题的更多详细信息,请参阅Backbone docs

    【讨论】:

    • 问题是我在那个 router.on 中使用了 id 那么如何将 id 传递给它呢?
    • 查看我对如何取消绑定和重新绑定事件所做的编辑
    • 那么基本上所有内容都会在再次调用时再次绑定,因为它导航到新页面对吗?
    • 是的,在这种情况下,您只需要一个用于 Advance() 和 moveBack() 函数的绑定,只要您不断增加每个新页面的 id 即可
    • 我试过 vent.off('next');和以前一样,但它似乎仍然增加了两倍,所以必须这样做,但我认为另一个答案也需要在我取消绑定视图的地方完成,等等......你知道我怎样才能正确地实现它吗?
    【解决方案2】:

    问题是每次更改路线时都会创建一个新视图,但永远不会删除旧视图。每次点击下一个,您的浏览量可能会翻倍!

    这里有一个帖子可能会有所帮助:

    Disposing of view and model objects in Backbone.js

    【讨论】:

    • 你能给我举个例子吗...我尝试在调用触发器后删除视图,但它只是完全删除了视图
    猜你喜欢
    • 2016-03-31
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    • 2012-04-24
    相关资源
    最近更新 更多