Javascript 主干模型对象。。。。它们存储在哪里,以便DOM可以与它们交互?

Javascript 主干模型对象。。。。它们存储在哪里,以便DOM可以与它们交互?,javascript,jquery,backbone.js,backbone-views,backbone-events,Javascript,Jquery,Backbone.js,Backbone Views,Backbone Events,我才意识到我根本不知道自己到底在干什么。我是在试图找出一种切实可行的策略来删除模型上视图的事件侦听器时认识到这一点的。然后我问“好吧,既然视图已经呈现给DOM,那么模型在哪里?”然后我问“我在函数体中创建的这个模型对象是怎么回事,既然我已经将视图呈现给DOM,那么它就不在范围之内了,维护状态?” 啊,啊,啊,啊 前 视图构造函数 Timeclock.Views.JobNewView = Backbone.View.extend({ template: JST['jobs/_form'],

我才意识到我根本不知道自己到底在干什么。我是在试图找出一种切实可行的策略来删除模型上视图的事件侦听器时认识到这一点的。然后我问“好吧,既然视图已经呈现给DOM,那么模型在哪里?”然后我问“我在函数体中创建的这个模型对象是怎么回事,既然我已经将视图呈现给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的函数

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);
}
那么,我传递给视图对象的模型是如何持久化的,以便DOM交互可以在底层模型对象上设置属性值的呢

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

我可以想出两种方法:

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

2) 主干网正在创建一些对象名称空间,视图知道它在哪里存储支持DOM的模型和集合。我有种感觉是1,但谁知道呢

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

任何能给予的帮助都将不胜感激。有生存危机的

谢谢

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

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

var name = 'Peter';
var person = new Backbone.Model({ name: 'Peter' });
var view = new Backbone.View({ model: person } );
。。。然后,
name
person
view
都只是内存中的对象。它们与jQuery无关;它们与DOM无关。如果实现
render()
,视图恰好能够创建DOM元素,但即使这样,这些元素也不必附加到页面的活动DOM

。。。在上面的示例中,DOM事件是如何作用于底层模型对象的?一旦renderCollaboratingView()函数退出,我传递给视图的模型如何与之交互

根据您展示的代码,模型没有直接与之交互。您的
事件
哈希

events:{
    'blur #job_form :input':'assignValue'
},
。。。表示在
job\u表单
元素中发生
blur
事件时,它将在名为
assignValue
的视图上调用一个方法。该方法可能会与模型交互(可能会,对吧?),但DOM事件根本不会直接导致与模型的交互

如果主干视图实际上只是jquery对象,那么当支持jquery对象的元素从DOM中删除时,jquery侦听器不是从DOM元素中删除了吗

主干网的侦听器与jQuery侦听器完全不同。他们倾听以主干为中心的事件。查看主干组件触发的内置事件列表。视图的事件哈希是一个很好的约定,用于侦听DOM事件;它基本上围绕jQuery的事件委派概念

如果我不打算完全破坏视图并将其保存以供以后使用,是否只需要删除侦听器

如果不删除侦听器,则无论侦听组件是否更改页面,只要相关事件发生,侦听器都将继续运行。假设您有一个主干。视图执行以下操作:

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

    _onClick: function() {
         this.$el.append('Clicked!');
    }
 });
每当页面上发生任何
click
DOM事件时,此视图将追加
Clicked到其内部DOM元素。当视图附加到页面的DOM时,
单击将在每次单击时显示。当视图从DOM中删除时,该函数仍将在每次单击时运行。。。但是由于视图的内部根元素没有附加到任何东西,因此函数将没有任何效果


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

JavaScript有垃圾收集功能。对象不会被破坏,然后它们就会超出范围。当对象
X
看到没有人引用(或指向)到
X
时,该对象将被运行时系统收集垃圾

主干视图也是一个对象。一个对象可以存储对另一个对象的引用

在您的
渲染协作视图中
,您写道:

  var model_view = new this.ViewConstructor({model: job});
模型视图
是视图的对象。您通过了您的
工作
,这是您从以下渠道获得的模型:

 renderCollaboratingView: function(e){
    var job = this.model; 
    ....
 }
您可以在主干带注释的代码中查看这一行:。(我建议您阅读答案后再查看链接)

电话是:

var viewOptions = ['model', 'collection', 'el', 'id', 
                   'attributes', 'className', 'tagName', 'events'];
然后主干视图被定义为:

它是:

 var View = Backbone.View = function(options) {
    this.cid = _.uniqueId('view');
    options || (options = {});
    _.extend(this, _.pick(options, viewOptions));
    this._ensureElement();
    this.initialize.apply(this, arguments);
  };
看这行:

 _.extend(this, _.pick(options, viewOptions));
以及您的代码:

 var model_view = new this.ViewConstructor({model: job});
那么,我传递给视图对象persis的模型是怎样的呢
initialize: function(options){
     this.listenTo(this.model, 'failed-request', this.failedLocationRequest);
     ....