【问题标题】:Code from multiple view instances causing conflicts来自多个视图实例的代码导致冲突
【发布时间】:2013-02-25 07:01:59
【问题描述】:

我正在使用 Backbone 将 Web 服务移植到单页 Web 应用程序中。有一个基本布局,由页眉组成,一个空的div#content 我在其中附加视图和页脚。

每条路由都会创建相应的视图并将其附加到div#content,将之前渲染的视图替换为新视图。

我正在使用require.js 加载主干应用程序及其依赖项。 所有 Backbone 代码都很小,只有一个文件,因为我只使用路由器和视图。 此 AMD 模块依赖于视图中使用的 util.js 文件导出函数。 创建并呈现视图后,它会从 util.js 执行所需的实用程序(jquery 内容、ajax 等)。

问题是,当我渲染一个视图时,它的实用程序被调用,当我导航到另一条路线并创建一个新视图时,现在调用新视图的实用程序,但旧视图的实用程序仍在运行。

在某些时候,我同时运行了来自大约五个视图的实用程序,有时会导致冲突。

很明显,我的方法不够好,因为我应该有办法将 stop/start 实用程序功能作为某种服务。

我将粘贴显示我当前方法的相关代码:

require(["utilities"], function(util) {
...
Application.view.template = Backbone.View.extend({
  el: "div#content",
  initialize: function(){
    this.render();
  }, 
  render: function(){
    var that = this;
    // ajax request to html
    getTemplate(this.options.template, {
      success: function(template) {
        var parsedTemplate = _.template( template, that.options.templateOptions || {});
        that.$el.html(parsedTemplate);
        // execute corresponding utilities
        if(that.options.onReady) {
          that.options.onReady();
        }
      },
      error: function(template) {
        that.$el.html(template);
      }
    })
  }
});
...
Application.router.on('route:requestPayment', function(actions) {  
  var params = { template: 'request-payment', onReady: util.requestPayment };
  var view = new Application.view.template(params);
});       
...

});

util.requestPayment 包含一个函数,其中包含使模板工作所需的所有内容。

我对如何处理这个问题感到困惑。我希望我很清楚,任何建议或帮助将不胜感激。

编辑:utilities.jssn-p:

...

var textareaCounter = function() {
  $('#requestMessage').bind('input propertychange', function() {
    var textarea_length = 40 - $(this).val().length;
    if(textarea_length === 40 || textarea_length < 0) {
      $('#message-counter').addClass('error').removeClass('valid');
      $("#submitForm").attr('disabled', 'disabled');
    }
    else if(textarea_length < 40 && textarea_length > 0) {
      $('#message-counter').removeClass('error');
      $("#submitForm").removeAttr('disabled');
    }
    $('#message-counter').text(textarea_length);
  });
}
...    
var utilities = utilities || {};
...
utilities.requestPayment = function() {      
  textareaCounter();
  initForm();
  preventCatching();
  requestPaymentCalcFallback();
};
...
return utilities;
...

【问题讨论】:

  • 为什么要从initialize()内部调用.render()?能否请您发布一个实用程序.js 文件的 sn-p,它有什么作用?
  • @mamoo 为了避免不得不从另一行渲染它们。
  • @mamoo, utility.requestPayment 这正是模块公开的内容。我只复制了一个函数的定义。其他的类似,只是 jquery 的东西和一些 ajax 轮询

标签: javascript backbone.js


【解决方案1】:

我建议您应该在应用中的某处存储对当前活动视图的引用。

您在这里创建一个新视图:

var view = new Application.view.template(params);

但之后您将无法访问此变量。所以它存在,但你不能停止/删除/摆脱它。

我们通常做的是有一个 Parent App 类来初始化整个应用程序并管理所有内容。你在 requirejs 中的每个模块都会依赖它。当一条新路线正在导航时,您要求 Parent App 类更改视图。它将删除旧视图,创建一个新视图,填充 div#content 然后存储它的引用。

我认为当您删除旧视图时,所有实用程序都会停止响应它。

如果您仍然遇到调用事件的问题,那么您可能需要在删除视图引用之前使用stopListening 事件绑定器。

【讨论】:

猜你喜欢
  • 2023-03-26
  • 2015-04-25
  • 1970-01-01
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
  • 2016-04-24
  • 2011-06-05
  • 1970-01-01
相关资源
最近更新 更多