javascript - 主干模型对象....它们存储在哪里以便 DOM 可以与它​​们交互?

标签 javascript jquery backbone.js backbone-views backbone-events

我刚刚意识到,当涉及到主干时,我不知道我到底在做什么。当我试图找出一个有说服力的策略来移除模型上 View 的事件监听器时,我意识到了这一点。然后我问“好吧,既然 View 已经渲染到 DOM,那么模型到底在哪里?”然后我问“我在函数体内创建的这个模型对象如何,现在我已经将 View 呈现给 DOM,因此超出范围,维护状态?” 啊啊啊啊啊!!!!!!!!!

例。

查看构造函数

Timeclock.Views.JobNewView = Backbone.View.extend({
  template: JST['jobs/_form'],
  events:{
   'blur #job_form :input':'assignValue'
  },
  initialize: function(options){
    this.listenTo(this.model, 'failed-request', this.failedLocationRequest);
    this.listenTo(this.model, 'updated-location', this.updatedLocation);
    this.listenTo(this.model, 'sync', this.renderJobView); 
    this.listenTo(this.model, 'invalid', this.displayModelErrors);
    this.listenTo($(window), 'hashchange', this.clearListeners);
  },
  render: function(){
    this.$el.html(this.template({attributes: this.model.attributes}));
    this.$el.find('#address_fields').listenForAutoFill();
    return this;
  },
  assignValue: function(e){
    var $field = $(e.currentTarget)
    var attr_name = $field.attr('name');
    var value = $field.val();
    this.model.set(attr_name, value);
  }...
});

向 DOM 渲染 View 的函数

renderCollaboratingView: function(e){
  var job = this.model;
  var $row = $(e.currentTarget);
  job.set({customer_id: $row.data('id')});
  var model_view = new this.ViewConstructor({model: job});
  $container.html(model_view.render().el);
}

那么我传递给 View 对象的模型是如何持久化的,以便 DOM 交互可以在底层模型对象上设置属性值?

我知道主干 View 只是一个包装器,用于以声明方式编写 DOM 监听器,但 DOM 事件如何作用于上面示例中的基础模型对象?一旦 renderCollaboratingView() 函数退出,我传递给 View 的模型如何仍在与之交互?

我可以想到两种方法:

1) 模型对象通过jquery 对象绑定(bind)到DOM。我在我的 View 中声明的所有事件监听器都知道底层模型对象在 jquery 对象上的位置(“模型”属性?)。

2) Backbone 正在创建一些对象 namespace , View 知道它存储支持 DOM 的模型和集合的位置。我感觉它排名第一,但谁知道呢。

再一次,我来到这里是因为我试图理解为什么我需要删除我首先传递到 View 中的模型上的监听器。如果主干 View 真的只是 jquery 对象,那么当支持 jquery 对象的元素从 DOM 中删除时,jquery 监听器不会从 DOM 元素中删除吗?如果我不打算完全破坏 View 并将其保存以备后用,是否只需要删除监听器?

如能提供任何帮助,我们将不胜感激。存在生存危机。

谢谢

最佳答案

So how is the model that I am passing to the view object persisted so that the DOM interactions can set attribute values on the underlying model object?

主干模型和 View 只是存在于页面范围内存中的 Javascript 对象(与任何其他 Javascript 一样)。如果你要做...

var name = 'Peter';
var person = new Backbone.Model({ name: 'Peter' });
var view = new Backbone.View({ model: person } );

... 那么namepersonview 都只是内存中的对象。它们与 jQuery 无关;它们与 DOM 无关。如果您实现 render(),View 恰好能够创建 DOM 元素,但即便如此,这些元素也根本不必附加到页面的实时 DOM。

... how are DOM events acting on the underlying model object in the example above? As soon as the renderCollaboratingView() function has exited how is the model that I passed to the view still being interacted with?

根据您显示的代码,模型没有直接交互。您的 events 散列 ...

events:{
    'blur #job_form :input':'assignValue'
},

...确实表示,每当 job_form 元素中发生 blur 事件时,它都会在 View 上调用一个名为 assignValue 的方法>。该方法可能会与模型交互(它可能会,对吧?),但 DOM 事件根本不会直接导致与模型的交互。

If backbone views are really just jquery objects then aren't jquery listeners removed from DOM elements when the element backing the jquery object is removed from the DOM?

Backbone 的监听器与 jQuery 监听器完全不同。他们监听以 Backbone 为中心的事件。 See here用于 Backbone 组件触发的内置事件列表。 View 的事件哈希是一个很好的约定,用于监听 DOM 事件;基本上是a nice wrapper围绕事件委托(delegate)的 jQuery 概念。

Do I only need to remove the listeners if I am going to not destroy the view entirely and save it for later use?

如果您不删除监听器,只要相关事件发生,它们就会继续运行,无论监听组件是否正在更改页面。假设你有一个 Backbone.View 做这样的事情:

var MyView = Backbone.View.extend({
    // ...
    events: {
        // Don't do this!
        'click': '_onClick'
    },
    // ...

    _onClick: function() {
         this.$el.append('Clicked!');
    }
 });

任何时候在页面上发生任何 click DOM 事件,此 View 都会将文本 Clicked! 附加到其内部 DOM 元素。当 View 附加到页面的 DOM 时,Clicked! 将在每次点击时出现。当 View 从 DOM 中移除时,该函数将仍然在每次点击时运行...但是由于 View 的内部根元素没有附加到任何东西,该函数将不起作用。

这是一种内存泄漏,因为 MyView 的任何实例都将被垃圾收集器清除。但特别邪恶的副作用是它使用 CPU 时间来做一些完全没有值(value)的事情。现在想象一下事件监听器是否做了任何重要的事情。页面的性能将受到影响。

关于javascript - 主干模型对象....它们存储在哪里以便 DOM 可以与它​​们交互?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29423770/

相关文章:

javascript - 新创建的按钮(通过 createElement ("Button"))激活自身。如何阻止它?

javascript - 让多个按钮在 ReactJS 中调用一个函数

jquery - 将值传递给 jquery 对话框表单

javascript - 主干滚动事件未触发

javascript - netsuite是否支持preventDefault()?

javascript - 子对象调用兄弟对象的方法

javascript - RxJS 使用两个参数订阅

javascript - 使用javascript隐藏Html元素

javascript - 未捕获的类型错误 : Cannot call method 'then' of undefined

jquery - 如何使用 jQuery 更改链接