【问题标题】:Angular cant read object in array角度无法读取数组中的对象
【发布时间】:2015-03-12 11:50:31
【问题描述】:

我有一个数组,其中有两个对象,分配给 $scope.items;

当我这样做时

console.log($scope.items) 

输出是:

[
 {s: "item1", q: 3, $$hashKey: "object:3", population: Object},
 {s: "item2", q: 3, $$hashKey: "object:4", population: Object}
]

但是当我这样做时

console.log($scope.items[0]) 

输出(有时*)是:

{s: "item1", q: 3, $$hashKey: "object:3"}

'* 这并不总是发生,取决于页面加载。刷新页面时,结果有时有人口,有时没有。

第一个输出始终是完整的,总体保持不变。 (无论我按 F5 多少次 :))

我同时调用了 console.log。和上面的顺序一样。

所以我不明白当我直接调用其中一个对象时它们是不完整的?

看起来像是解析错误,但第一个输出怎么总是完整的呢?

额外信息 $scope.items 是另一个数组的副本。

我使用 $http.get 构建对象,但也尝试在他的成功函数中调用 console.logs。

$http.get 被放置在一个 foreach 中,因此在完整数组完成之前被多次调用

我使用 http.get 来构建人口。

我希望有人可以为我澄清一下,这怎么可能。或者如何继续寻找找到错误的可能性。

【问题讨论】:

  • 你是怎么得到$scope.items的?并填补人口?
  • 我最近注意到,当您调用 console.log($scope.items) 时,它会按引用记录,但当您调用 console.log($scope.items[0]) 时,它会按值记录,请尝试执行 console.log(angular.copy($scope.items))
  • 我忘了提我先用 $scope.items = angular.copy($scope.other); 复制对象;
  • 你能发布所有代码吗?包括http获取
  • 我在这个 plunker 中为你制作了工作 plunker plnkr.co/edit/QPB2JW8OAA4TiLgH1g6j?p=preview 我在成功方法中使用 $http 我更改了对象,然后在 finally 我 console.log 中它总是会格式正确

标签: javascript arrays angularjs object


【解决方案1】:

这不是 Angular 的问题,它是谷歌浏览器的功能/问题。在谷歌浏览器中,当您控制台任何对象时,它会显示名称:对象,当您展开它时,它会指向实时内存位置,即使该内存位置在 console.log 之后更新,它也会随着更新的输出而扩展。

var d=[];

for(var i=0;i<100;i++){
    d[i]="val_"+i
}
console.log(d); //d[60] should be val_60 but will get value 'changed value' when you expand
console.log(d[60]); //will print 'val_60'

d[60]='changed value'

这是一个示例代码,您可以在浏览器中运行,您会在控制台中得到奇怪的结果。

在您的情况下,您正在打印一个数组,谷歌浏览器的控制台将指向该数组的内存位置。并打印该数组,当您尝试扩展该数组时,它将从内存中获取进餐时间信息并显示您当前的数组状态。

解决方案是在 chrome 中使用调试器并在该变量发生更改之前检查该变量。

另一种解决方案是使用 JSON.stringify 将该数组转换为字符串,

【讨论】:

  • ok 谢谢,但我需要使用人口值。它说无法读取未定义的属性“人口”。
  • 当您使用 console.log 时,您的人口属性不在该对象中
  • 你是使用http调用还是本地存储??
  • $http.get 在 foreach 中,我还尝试在 foreach 完成后运行 console.logs
  • 然后你的值不会在你的 foreach 循环之后更新,该值会在完成可能在 success() 或 error() 中的 ajax 调用后更新。尝试登录成功方法,你会得到你的结果。你可以试试promise,但你需要按照你的逻辑使用它
【解决方案2】:

当您在通过某种方法处理之前记录值时,您面临的是一个竞争问题,您应该熟悉 Promise 和 $http $http 的工作示例及其承诺

http://plnkr.co/edit/QPB2JW8OAA4TiLgH1g6j?p=preview

$http.get()
.success(function() {
    $scope.data = [{
      s: "item1",
      q: 3,
      $$hashKey: "object:3"
    }, {
      s: "item2",
      q: 3,
      $$hashKey: "object:4"
    }]
    angular.forEach($scope.data, function(obj){
      obj.population = {}
    })
  })
  .finally(function() {
    console.log($scope.data[0].population)
  })

【讨论】:

    【解决方案3】:

    似乎在第一次控制台日志之后,某些事件正在从项目中删除人口字段,或者可能正在使用默认值重新初始化项目。为了更好地调试它,请使用 JSON.strinfigy 项目的结果记录对象,例如console.log(JSON.stringify($scope.items)

    如果没有 stringify,任何改变对象的代码/事件也会更新控制台日志。

    【讨论】:

    • 可能有事件和异步操作可以改变对象,即使它们之间没有代码。你有没有在控制台中对对象进行字符串化后检查结果?
    • 我现在做了,结果是一样的
    猜你喜欢
    • 2018-08-24
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 2018-07-16
    • 2020-04-24
    相关资源
    最近更新 更多