每个函数中的 Javascript 新对象没有像我想象的那样工作

标签 javascript backbone.js for-loop underscore.js new-operator

我在 forEach 循环期间创建一个新的 Backbone 模型,然后在内部运行另一个 forEach 循环并创建另一个 Backbone 模型并将其作为属性传递回前一个模型。

但是到最后,子模型似乎已添加到所有第一级模型中。

http://jsfiddle.net/ZBvV4/

var page =
 { rows:
    [
      { layout: '1:1:1'
      , columns:
        [ 
          { widgets: 
              [
                {
                  type: 'twitter'
                }
              , {
                  type: 'facebook'
                }
              ]
          }
        , { widgets: 
              [
                {
                  type: 'image-slider'
                }
              , {
                  type: 'instagram'
                }
              ]
          }
        , { widgets: 
              [
                {
                  type: 'instagram'
                }
              ]
          }
        ]
      }
    , { layout: '2:1'
      , columns:
        [ 
          { widgets: 
              [
                {
                  type: 'twitter'
                }
              ]
          }
        , { widgets: 
              [
                {
                  type: 'image-slider'
                }
              ]
          }
        ]
      }
    ]
 }

var app = {
  models: {}
, collections: {}
, views: {}
}

app.models.Row = Backbone.Model.extend({
  childColumns: []
})

app.models.Column = Backbone.Model.extend({
  childWidgets: []
})

var renderedRows = []

_.each(page.rows, function (row, rowIndex) {
  ////////////// * ROWS * //////////////
  var rowModel = new app.models.Row({
    layout: page.rows[rowIndex].layout
  })
  renderedRows.push(rowModel)

  _.each(row.columns, function (column, columnIndex) {
    ////////////// * COLUMN * //////////////
    var columnModel = new app.models.Column()
    rowModel.childColumns.push(columnModel)
  })
})

console.log('first row child columns', renderedRows[0].childColumns)
console.log('second row child columns', renderedRows[1].childColumns)

最佳答案

发生这种情况是由于您定义模型的方式所致。

app.models.Row = Backbone.Model.extend({
  childColumns: []
})

问题在于定义中的 childColumns 被设置为空数组 []new 不会每次都创建一个新数组,它会为每个模型分配相同的数组引用。这意味着您创建的所有 Row 条目都引用同一个数组。

您不需要在每次创建新条目时创建一个新数组,而不是引用单个数组:

app.models.Row = Backbone.Model.extend({
  childColumns: null
})

app.models.Column = Backbone.Model.extend({
  childWidgets: null
})

// ...

_.each(page.rows, function (row, rowIndex) {
  var rowModel = new app.models.Row({
    layout: page.rows[rowIndex].layout
  })
  // Initialize a new array here
  rowModel.childColumns = []
  renderedRows.push(rowModel)

  _.each(row.columns, function (column, columnIndex) {
    var columnModel = new app.models.Column()
    // Initialize a new array here
    columnModel.childWidgets = []
    rowModel.childColumns.push(columnModel)
  })
})

这是一个修复了问题的 jsFiddle:http://jsfiddle.net/5Epxz/1/

如果您希望模型更加具有 Backbone 风格,您还可以在模型的 initialize 方法中进行数组初始化。

关于每个函数中的 Javascript 新对象没有像我想象的那样工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17651978/

相关文章:

javascript - Highcharts:共享工具提示格式化程序 this.points[i]

javascript - 如何使用 javascript 正则表达式来验证城市名称?

javascript - 主干 - 管理应用程序 View

c - 在 SDL2 C 中使用 for 循环显示矩形

javascript - 如何找到子图

javascript - 如何使范围偏移与多行 contenteditable div 中的 HTML 元素一起使用?

javascript - Couchdb、couch-connector 和多个数据库

javascript - 全局 JS 变量的令人困惑的未捕获引用错误

C++程序不会进入for循环

c++ - Eclipse CDT 适用于