在 Dom 重复内修改 HTML

Modify HTML within a Dom-repeat

我被困在一个基本的东西上,但使用 Polymer 会变得非常复杂。我想根据其中的值更改 table 单元格的文本颜色。我试过在 dom-repeat 中使用 filter,但它不起作用,因为我不知道如何以这种方式访问​​ HTML。

示例代码如下:

    <h4>[[propertiesList.length]] Properties available</h4>
    <paper-card elevation="1">
        <div class="tableRow title">
            <div class="title colM">Name</div>
            <div class="title colL">URL</div>
            <div class="title colM">Owned by</div>
            <div class="title colS">Created</div>
            <div class="title colM">Videos count</div>
            <div class="title colM">Status</div>
            <div class="title colXS">Edit</div>
        </div>
        <template is="dom-repeat" items="[[propertiesList]]" filter="StatusColor">
            <div class="tableRow">
                <div class="colM">[[item.name]]</div>
                <div class="colL">[[item.url]]</div>
                <div class="colM">[[item.user.name]]</div>
                <div class="colS">[[item.created]]</div>
                <div class="colM">[[item.videos_count]]</div>
                <div class="colM" id="status">[[item.status.label]]</div>
                <div class="colXS left"><paper-icon-button class="editIcon" on-tap="editProperty" icon="mdi:pencil"></paper-icon-button></div>
            </div>                
        </template>
    </paper-card>

和 JS:

        StatusColor: function (item) {
            if (item.status.label == "Active") {
                document.getElementById("status").style.color = '#48C8B6';
                console.log("Property is active");
                return item.status.label;
            }
        },

...对我的文本颜色没有任何影响。

然后,我尝试了一个很好的旧 for 循环,但由于某种原因,我无法获得正确的 .length 值。这是与上面相同的 HTML 减去 filter,并且 "status" 现在是 class 而不是 id。 JS如下:

        attached: function () {
            this.async(function () {
                var status = document.getElementsByClassName("status");
                console.log("Status value : ", status);
                var count = status.length;
                console.log("count value : ", count);
                for (i = 0; i < count; i++) {
                    var text = status[i].innerText;
                    if (text == "Active") {
                        status[i].style.color = "#48C8B6";
                    } else {
                        status[i].style.color = "#F1412E";
                    }
                }
            });

我的第一个 console.log 显示 status 值是正确的。我得到了我所有的 "status" div,Chrome Dev Tools 中的 length 属性 是正确的,但是第二个 console.log ( "count" 一个)总是显示 0。因此,我无法使 for-loop 正常工作。

帮帮我 (...obiwan kenobi)

请注意,模板 filter 用于从您的转发器中过滤掉项目(而不是像您尝试做的那样映射项目)。此外,模板转发器在 标记项目之前调用 filter 回调 。在第一次迭代中,#status 节点尚未被标记,因此 document.getElementById('status') 将 return null(假设不存在 ID 为 status 的其他节点已经),导致 TypeError 并且没有为该模板转发器呈现任何内容。

我推荐以下内容,而不是模板过滤器或 attached 回调:

  • CSS 默认和活动状态的样式(在 JS 中保留行为逻辑,在 CSS 中保留样式)
  • 有条件地分配 class 状态 div(使用 computed binding with attribute binding

如:

// style
.status {
  color: #F1412E;
}
.status.active {
  color: #48C8B6;
}

// template ($= for native attribute binding)
<div class$="[[_computeStatusStyle(item.status.label)]]">[[item.status.label]]</div>

// script
Polymer({
  _computeStatusStyle: function(label) {
    var baseStyle = "colM status";
    var activeStyle = label === "Active" ? " active" : "";
    return baseStyle + activeStyle;
  }
});

<head>
  <base href="https://polygit.org/polymer+1.5.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="paper-card/paper-card.html">
</head>

<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <style>
      paper-card {
        width: 100%;
      }
      .tableRow {
        margin: 1rem;
        border-bottom: solid 1px lightgray;
      }
      .status {
        color: #F1412E;
      }
      .status.active {
        color: #48C8B6;
      }
    </style>

    <template>
      <h4>[[propertiesList.length]] Properties available</h4>
      <paper-card elevation="1">
        <template is="dom-repeat" items="[[propertiesList]]">
          <div class="tableRow">
            <div class="colM">[[item.name]]</div>
            <div class="colL">[[item.url]]</div>
            <div class="colM">[[item.user.name]]</div>
            <div class="colS">[[item.created]]</div>
            <div class="colM">[[item.videos_count]]</div>
            <div class$="[[_computeStatusStyle(item.status.label)]]">[[item.status.label]]</div>
            <div class="colXS left">
              <paper-icon-button class="editIcon" on-tap="editProperty" icon="mdi:pencil"></paper-icon-button>
            </div>
          </div>
        </template>
      </paper-card>
    </template>
    <script>
      HTMLImports.whenReady(function() {
        "use strict";

        Polymer({
          is: 'x-foo',
          properties: {
            propertiesList: {
              type: Array,
              value: generateProperties
            }
          },
          _computeStatusStyle: function(label) {
            var baseStyle = "colM status";
            var activeStyle = label === "Active" ? " active" : "";
            return baseStyle + activeStyle;
          }
        });

        /** Value generator for <x-foo>.propertiesList above */
        function generateProperties() {
          var props = [];
          for (var i = 0; i < 5; i++) {
            var statusLabel = i % 2 == 0 ? 'Active' : 'Inactive';
            props.push(new Property('name', 'url', 'username', 'created', 'videoCount', statusLabel));
          }
          return props;
        }

        /** Property class for <x-foo>.propertiesList above */
        function Property(name, url, username, created, videoCount, label) {
          this.name = name;
          this.url = url;
          this.user = {};
          this.user.name = username;
          this.created = created;
          this.videos_count = videoCount;
          this.status = {};
          this.status.label = label;
        };

      });
    </script>
  </dom-module>
</body>

codepen