Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/447.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 主干视图';在不同的实例中没有相同的数据,但确实有_Javascript_Backbone.js_Scope - Fatal编程技术网

Javascript 主干视图';在不同的实例中没有相同的数据,但确实有

Javascript 主干视图';在不同的实例中没有相同的数据,但确实有,javascript,backbone.js,scope,Javascript,Backbone.js,Scope,我有一个主干视图,其呈现函数中包含以下代码(请注意3console.log(that.ticketSelector.attributes);): 在控制台中,我看到: Object {icon: "ticket", title: "Tickets", columns: Array[4], classes: Array[2]} Object {icon: "warning-sign", title: "Alarms", columns: Array[4], classes: Array[2]} O

我有一个主干视图,其呈现函数中包含以下代码(请注意3
console.log(that.ticketSelector.attributes);
):

在控制台中,我看到:

Object {icon: "ticket", title: "Tickets", columns: Array[4], classes: Array[2]}
Object {icon: "warning-sign", title: "Alarms", columns: Array[4], classes: Array[2]}
Object {icon: "tasks", title: "Tasks", columns: Array[4], classes: Array[2]}
我希望:

Object {icon: "ticket", title: "Tickets", columns: Array[4], classes: Array[2]}
Object {icon: "ticket", title: "Tickets", columns: Array[4], classes: Array[2]}
Object {icon: "ticket", title: "Tickets", columns: Array[4], classes: Array[2]}
以下是我的DataTable视图:

var DataTable = Backbone.View.extend({

tag: 'div',
className: 'data-table',

initialize: function(opts) {
    if(typeof opts.parent !== 'undefined') {
        this.parent = opts.parent;
    }
    if(typeof opts.icon !== 'undefined') {
        this.attributes.icon = opts.icon;
    }
    if(typeof opts.title !== 'undefined') {
        this.attributes.title = opts.title;
    }
    if(typeof opts.columns !== 'undefined') {
        this.attributes.columns = opts.columns;
    }
    if(typeof opts.customClasses !== 'undefined') {
        this.attributes.classes = opts.customClasses;
    }
},

attributes: {},

template: function() {
    var temp;

    $.ajax(root + 'templates/data-table.html', {
        success: function(data) {
            // console.log(data);
            temp = Mustache.compile($(data).filter('#data-table-template').html());
        },

        async: false
    });

    return temp;
}(),

events: {
},

serialize: function() {
    var that = this;
    return {
        root: root,
        icon: that.attributes.icon,
        title: that.attributes.title,
        columns: that.attributes.columns
    };
},

resize: function() {
    var that = this;
},

subView: [],

render: function() {
    var that = this;

    var html = this.template(this.serialize());

    this.$el.html(html);

    if(that.attributes.classes) {
        _.each(that.attributes.classes, function(c) {
            that.$el.addClass(c);
        });
    }

    this.collection.each(function(row) {
        tempView = new DataTableRow({ model: row, parent: that, columns: that.attributes.columns });
        that.subView.push(tempView);
        that.$('.tbody').append(tempView.$el);
        tempView.render();
    });

    this.$('.tbody').mCustomScrollbar({
        scrollInertia: 0,
    });

    return this;
}

});

var DataTableRow = Backbone.View.extend({

tag: 'div',
className: 'tr',

initialize: function(opts) {
    var that = this;

    if(typeof opts.parent !== 'undefined') {
        this.parent = opts.parent;
    }

    if(typeof opts.columns !== 'undefined') {
        var temp = {};
        that.attributes.columns = _.map(opts.columns, function(col) {
            return {
                text: that.model.get(col.modelKey),
                col: col.col
            };
        });
    }
},

attributes: { columns: [] },

template: function() {
    var temp;

    $.ajax(root + 'templates/data-table.html', {
        success: function(data) {
            // console.log(data);
            temp = Mustache.compile($(data).filter('#data-table-row-template').html());
        },

        async: false
    });

    return temp;
}(),

events: {
},

serialize: function() {
    var that = this;
    return {
        root: root,
        columns: that.attributes.columns
    };
},

resize: function() {
    var that = this;
},

render: function() {
    var that = this;

    var html = this.template(this.serialize());

    this.$el.html(html);

    return this;
}

});
我知道我可以通过为每个数据表创建不同的视图来解决这个问题,但这应该是可行的,我不知道为什么不行。有人帮忙吗?谢谢

编辑:为了更好地理解这一点,下面是下划线扩展函数:

_.extend = function(obj) {
  each(slice.call(arguments, 1), function(source) {
    if (source) {
      for (var prop in source) {
        obj[prop] = source[prop];
      }
    }
  });
  return obj;
};

是什么使这些属性附加到原型上的?

您的
属性位于原型上,因此它将在对象的所有实例中共享。每个实例都需要一个
属性
对象

而不是像这样:

var DataTable = Backbone.View.extend({
  attributes: {}
});
您需要在每次初始化时创建一个新对象:

var DataTable = Backbone.View.extend({
  attributes: {},
  initialize: function(options){
    this.attributes = {};
  }
});
正如@muistooshort所指出的,您的
子视图
数组和
DataTableRow.prototype.attributes也有这个问题。传递给
extend
的对象中的任何键值对都放置在对象的原型上,这意味着对象的新实例都将共享这些属性。这就是您的所有函数在每个实例上结束的方式,但也意味着其他所有功能都会结束,因此,您需要确保每个实例的初始化都正确

编辑
Backbone.View.extend
\ucode.extend
无关,只是它碰巧使用了一个助手,就像其他代码一样

  • \uux.extend
    获取多个对象并将其属性复制到第一个对象上
  • Backbone.View.extend
    接受单个对象,并返回一个新的构造函数,该构造函数将构造一个以该对象为原型的对象,并且还继承调用
    extend
    的第一个构造函数的原型

假设你有一个这样的物体:

var DataTable = Backbone.View.extend({
  attributes: {}
});
Backbone.View
构造函数,调用该构造函数时将创建一个新对象,该对象具有
Backbone.View.prototype
作为其具有标准视图方法的原型

当您执行
var DataTable=Backbone.View.extend(newproto_obj)
时,您现在拥有以下功能:

DataTable
构造函数,调用该构造函数时将创建一个新对象,该对象具有一个原型,其值来自
newproto\u obj
,并将
Backbone.View.prototype
作为该原型的原型


这就是所谓的原型链,JavaScript就是这样继承的。创建新对象时,它没有自己的属性,除非它们由构造函数中的主干或
initialize
函数设置。如果您试图访问对象上的某个属性,但该属性不存在,它将查看其原型是否具有该名称的属性。由于prototype对象是一个跨实例共享的单个公共对象,因此修改它将更改每个实例。

您的
属性位于prototype上,因此它将跨对象的所有实例共享。每个实例都需要一个
属性
对象

而不是像这样:

var DataTable = Backbone.View.extend({
  attributes: {}
});
您需要在每次初始化时创建一个新对象:

var DataTable = Backbone.View.extend({
  attributes: {},
  initialize: function(options){
    this.attributes = {};
  }
});
正如@muistooshort所指出的,您的
子视图
数组和
DataTableRow.prototype.attributes也有这个问题。传递给
extend
的对象中的任何键值对都放置在对象的原型上,这意味着对象的新实例都将共享这些属性。这就是您的所有函数在每个实例上结束的方式,但也意味着其他所有功能都会结束,因此,您需要确保每个实例的初始化都正确

编辑
Backbone.View.extend
\ucode.extend
无关,只是它碰巧使用了一个助手,就像其他代码一样

  • \uux.extend
    获取多个对象并将其属性复制到第一个对象上
  • Backbone.View.extend
    接受单个对象,并返回一个新的构造函数,该构造函数将构造一个以该对象为原型的对象,并且还继承调用
    extend
    的第一个构造函数的原型

假设你有一个这样的物体:

var DataTable = Backbone.View.extend({
  attributes: {}
});
Backbone.View
构造函数,调用该构造函数时将创建一个新对象,该对象具有
Backbone.View.prototype
作为其具有标准视图方法的原型

当您执行
var DataTable=Backbone.View.extend(newproto_obj)
时,您现在拥有以下功能:

DataTable
构造函数,调用该构造函数时将创建一个新对象,该对象具有一个原型,其值来自
newproto\u obj
,并将
Backbone.View.prototype
作为该原型的原型


这就是所谓的原型链,JavaScript就是这样继承的。创建新对象时,它没有自己的属性,除非它们由构造函数中的主干或
initialize
函数设置。如果您试图访问对象上的某个属性,但该属性不存在,它将查看其原型是否具有该名称的属性。因为原型对象是跨实例共享的单个公共对象,所以修改它将更改每个实例。

子视图也可能有相同的问题。还有其他的
属性
。我想我没有意识到主干的扩展应用到了原型中。主干使用下划线的扩展,它看起来像。。你能解释一下为什么它会出现在原型机上吗?查看下划线代码,它看起来只是在复制属性。我在问题中加入了下划线函数作为edit@TroyCosentino更新。可能是h