3

我有一个简单的<firebase-query>标签,我想在通过<dom-repeat>. 比如我需要把一些字段变成链接,还要解析一些日期。

所以,一旦数据准备好,我需要获取数据,遍历每个项目,并更改一些值。

为此,我对数据进行了观察,以检测数据何时准备就绪。但是,我不知道如何遍历该 JavaScript 函数中的数据。出于某种原因,for(var i in items)尽管这些项目确实存在,但它不起作用。

这是组件:

<dom-module id="cool-stuff">

  <template>

    <firebase-query id="query" path="/items" data="{{items}}"></firebase-query>

    <template is="dom-repeat" items="{{items}}" as="item">
      [[item.name]]<br />
      [[item.date]]<br />
    </template>

  </template>

  <script>
    Polymer({
      is: 'ix-table',
      properties: {
        items: {type: Object, observer: "_itemsChanged"},
      }
      itemsChanged: function(data) {
        // how do I loop through the data received from firebase-query?
        console.log(data);
      }
    });
  </script>

</dom-module>

理想情况下,我想要在观察者函数中做的就是:

for(var i in data) {
  obj = data[i];
  obj.name = '<a href="/item/"+obj.key>'+ojb.name+'</a>';
}

但我似乎无法遍历数据。

在观察者函数内部,console.log(data)返回一些奇怪的东西,如下所示:

Array[o]
0: Object (which contains a proper item)
1: Object (same)
2: Object (same)

更新:

这是 console.log(data) 返回的屏幕截图(从观察者内部):

在此处输入图像描述

该数组似乎填充了所有对象,但它显示为 Array[0]。所以它不会让我遍历它们。

更新 2:

感谢arfost,这是解决方案:

<script>
  Polymer({
    is: 'ix-table',
    properties: {
      items: {type: Object},

    }
    observers: [
      '_itemsChanged(items.splices)'
    ],
    _itemsChanged: function(changeRecord) {
      if (changeRecord) {
        changeRecord.indexSplices.forEach(function(s) {
          for (var i=0; i<s.addedCount; i++) {
            var index = s.index + i;
            var item = s.object[index];
            console.log('Item ' + item.name + ' added at index ' + index);
            // do whatever needed with the item here:
            this.items[index].name = "New name";
          }
        }, this);
      }
    },
  });
</script>
4

3 回答 3

4

<firebase-query>结果

请注意,这<firebase-query>会导致对象数组。假设您的数据库包含以下项目/notes/<USER_ID>/

在此处输入图像描述

<firebase-query>会看起来像这样:

<firebase-query
    id="query"
    app-name="notes"
    path="/notes/[[user.uid]]"
    data="{{notes}}">
</firebase-query>

user绑定到哪里<firebase-auth>.user)。

假设用户已登录,然后将使用以下数组<firebase-query>填充其data属性(即绑定到):notes

在此处输入图像描述

请注意每个对象如何包含一个$key属性,该属性对应于在 Firebase 控制台的数据库视图中看到的项目键。

然后你可以notes直接迭代<dom-repeat>

<template is="dom-repeat" items="[[notes]]">
  <li>
    <div>key: [[item.$key]]</div>
    <div>body: [[item.body]]</div>
    <div>title: [[item.title]]</div>
  </li>
</template>

绑定到 HTML 字符串

您应该知道,在这种情况下,字符串数据绑定按字面意思呈现,因此尝试设置nameobj.name = '<a href="...">'将呈现文字字符串而不是锚点。相反,您应该在模板中声明标签,并在这些标签内绑定keyname属性。因此,您的观察者可以替换为:

<template is="dom-repeat" items="{{items}}" as="item">
  <a href$="/item/[[item.key]]">[[item.name]]</a><br />
  [[item.date]]<br />
</template>

迭代数组

以下注释仅在您希望在显示数据之前对其进行变异时才相关...

迭代数组时,您应该避免for..in,因为它不能保证迭代的顺序,并且因为它可能会迭代您可能不一定关心的可枚举属性。相反,您可以使用for..of(假设 ES6 可用于您的应用程序):

for (let note of notes) {
  note.title += ' ...';
}

Array.prototype.forEach()

notes.forEach(function(note) {
  note.title += ' ...';
});
于 2017-01-03T06:41:32.380 回答
2

我想我遇到了和你一样的问题。

它来自于 firebase 查询获取数组的方式、聚合物观察者的工作方式,并且由于 javascript 控制台在显示对象时是基于引用的这一事实而被隐藏。

事实上,这里真正发生的是,firebase 查询正在创建一个空数组,这会触发您的聚合物观察者。

因此,一旦创建了数组,您的函数就会被调用,但仍然是空的,并且您无法迭代,因为它是空的。然后记录它,其中原语子属性正确显示(数组 [0])

然后firebase开始用数据填充数组。数组引用保持不变,因此聚合物不会再次触发观察者,并且在控制台中,当它尝试显示数组时,它会显示日志中引用的数组,该数组现在包含数据。

我建议您使用数组突变观察器代替简单的观察器,如下所示

`properties: {
    items: {type: Object},
  },
,
observers: [
       '_itemsChanged(items.splices)'
],`

每次将对象添加到数组时它都会触发,并且您将能够完成所需的工作:)

我有关于阵列突变观察者的文档的链接:) 聚合物阵列突变观察者

我希望这能解决您的问题,祝您有美好的一天。

于 2017-01-04T13:54:05.490 回答
0

我认为我无法想到需要通过遍历数组而不是仅使用计算绑定来改变数据的场景。像这样:

<template is="dom-repeat" items="{{items}}" as="item">
  <child-el date="{{_computeDate(item.date)}}"></child-el><br />
  <child-el attr1="{{_someOtherConversion(item.prop1)}}"></child-el><br />
  <child-el attr2="{{_iPromiseAnyConversionCanBeDoneLikeThis(item.prop2)}}"></child-el><br />
</template>
<script>
  _computeDate: function(item) {
    //do date converstion
}
于 2017-01-04T16:09:34.813 回答