【问题标题】:Polymer bounded property not updating (sometimes)聚合物有界属性未更新(有时)
【发布时间】:2015-06-11 19:25:13
【问题描述】:

1.0 有这个问题

我在聚合物元素中有以下 html

  <iron-selector attr-for-selected="step-number" selected="{{stepNumber}}">
    <section step-number="1">
      <page-1 id="page1"></page-1>
    </section>
    <section step-number="2">
      <page-2 id="page2"></page-2>
    </section>
    <section step-number="3">
      <page-3 id="page3"></page-3>
    </section>`

第 1 页触发事件 - event1,第 2 页触发 event2。这是我的聚合物元素的 javascript

function () {
  Polymer({
    is: 'name',
    ready: function() {
      this.stepNumber = 1;
      var firstStep = this.$.page1;
      var secondStep = this.$.page2;
      var thirdStep = this.$.page3;
      var that = this;
      firstStep.addEventListener('event1', function(e) {
        that.stepNumber = 2;                       // WORKING
      });
      secondStep.addEventListener('event2', function(e) {
        that.stepNumber = 3;                      // NOT WORKING
      });
    }
  });

这是有趣的部分: 两个事件都被触发,stepNumber 的值在event1 处理程序内部更新,但不在event2 处理程序内部更新。我还对此进行了调试,在event2 处理程序中,stepNumber 的值确实得到了更新(第 3 页元素获得了标签“iron-selected”),但它不会持续存在。一堆聚合物代码执行后,值又回到了2。

看起来像聚合物中的错误?

来自调试器的一些信息 -

在事件方法之后执行的聚合物代码基本上是执行事件处理程序的代码,然后是“手势识别”代码(我猜是点击),其中标签铁选择器被添加到页面-2 节

var recognizers = Gestures.recognizers;

for (var i = 0, r; i < recognizers.length; i++) 
{ 
   r = recognizers[i]; 
   if (gs[r.name] && !handled[r.name]) {
     handled[r.name] = true; // in here for r.name = "tap"
   r[type](ev); // type = click. ev = MouseEvent. ev.target = iron-selector
} 
}

深入挖掘 - 这将创建一个事件处理程序

_createEventHandler: function(node, eventName, methodName) {
var host = this;
return function(e) {
if (host[methodName]) {
hostmethodName;
} else {
host._warn(host._logf("_createEventHandler", "listener method " + methodName + " not defined"));
}
};

主机是铁选择器。 methodName 是 _activateHandler,其中第 2 页的部分调用了 _itemActivate

_activateHandler: function(e) {
      // TODO: remove this when https://github.com/Polymer/polymer/issues/1639 is fixed so we
      // can just remove the old event listener.
      if (e.type !== this.activateEvent) {
        return;
      }
      var t = e.target;
      var items = this.items;
      while (t && t != this) {
        var i = items.indexOf(t);
        if (i >= 0) {
          var value = this._indexToValue(i);
          this._itemActivate(value, t);
          return;
        }
        t = t.parentNode;
      }
    },
_itemActivate: function(value, item) {
      if (!this.fire('iron-activate',
          {selected: value, item: item}, {cancelable: true}).defaultPrevented) {
        this.select(value);
      }

_itemActivate 是 stepNumber 的值变为 2 的地方

【问题讨论】:

  • 您能否详细说明事件是什么以及它们是如何被触发的?您可能需要debounce 他们,或使用async 使stepNumber 分配等待Polymer 先完成它正在做的事情。
  • Zikes,这个聚合物元素就像一个工作流,每一页都像一个工作流步骤。工作流步骤完成时会触发这些事件。例如,page-1 是一个搜索页面。当用户单击搜索按钮时,会触发 event1。 Page-2 是搜索结果列表页面。当单击列表中的一项时,会触发 event2。你能详细说明一下异步吗? ?
  • 刚刚查看了事件方法执行后正在执行的聚合代码。它基本上是执行事件处理程序的代码,然后是“手势识别”代码,其中“stepNumber”的值神奇地回滚到 2 是这样的 - var recognizers = Gestures.recognizers; for (var i = 0, r; i &lt; recognizers.length; i++) { r = recognizers[i]; if (gs[r.name] &amp;&amp; !handled[r.name]) { handled[r.name] = true; r[type](ev); } }
  • 添加了更多信息。不知道有没有用

标签: javascript binding polymer


【解决方案1】:

清除iron-selectoractivateEvent属性(activate-event属性),像这样:

&lt;iron-selector attr-for-selected="step-number" selected="{{stepNumber}}" activate-event=""&gt;

【讨论】:

  • 嗨,斯科特,感谢您的“解决方法”,它有效。尽管您是否同意这是一个错误,并且它是否在您未来版本的雷达中?昨天我还在铁选择器上提交了一个错误,但没有得到回复。请确认。 github.com/PolymerElements/iron-selector/issues/35
  • 以上不是IMO的解决方法,它只是正确的用法。出于同样的原因,这不是 IMO 的错误,activateEvent 是铁选择器的一个功能,它允许元素自我选择。如果您想自己管理项目的选择,您可以清除该值,如图所示。
  • Scott,在这种情况下,来自 Google 同事的一些建议: 1. 添加相同的文档。 2.它应该默认禁用。作为用户,这是意料之中的。我不知道选择器如何或何时决定选择自己。对此的解释将是惊人的。
  • 这在iron-selector 中有记录。我不同意文档需要改进,我们正在努力,但它是一个庞大的材料语料库,我们是一个小团队。最后,默认值为 tap,因为这是迄今为止最常见的情况。
  • Fwiw,在iron-pages 中,我最近将其修改为不设置默认值activateEvent 以避免您在上面描述的确切问题。
【解决方案2】:

试试这个:

Polymer({
  is: 'name',
  ready: function() {
    this.stepNumber = 1;
    var firstStep = this.$.page1;
    var secondStep = this.$.page2;
    var thirdStep = this.$.page3;
    var that = this;
    firstStep.addEventListener('event1', function(e) {
      that.async(function(){
        that.stepNumber = 2;
      },0);
    });
    secondStep.addEventListener('event2', function(e) {
      that.async(function(){
        that.stepNumber = 3;
      },0);
    });
  }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多