聚合物纸张下拉的核心选择事件由另一个元素的核心选择器触发

时间:2014-09-18 01:53:09

标签: polymer paper-elements core-elements

我遇到了一个问题,其中paper-dropdown元素的on-core-select事件是由属于我的聚合物应用程序中的单独元素的核心选择器触发的。以下是聚合物元素的摘录,其中包括纸张下拉(以及聚合物事件脚本):

<paper-dropdown id="widthUnits" class="unitSelection" selected="{{item.data.designWidth[1]}}" on-core-select="{{ conditionUnitSelectionChanged }}" valueattr="label">
                        <paper-item label="mm"></paper-item>
                        <paper-item label="cm"></paper-item>
                        <paper-item label="m"></paper-item>
</paper-dropdown>


conditionUnitSelectionChanged: function(e, detail, sender) {
      // Ensure the selection has in fact changed
      if (sender.selected != detail.item.label)
      {                    
          this.ajaxUpdateUnit(sender);
      }
},

这里是核心选择器和相关代码,它是应用程序中完全不同元素的一部分。仅供参考,所有参与的两个元素中的聚合物'Changed'事件都会看到SelectedItemKey {/ 1}}。

<core-selector id="itemSelector" target="{{$.itemList}}" multi="false" selected="{{selectedItemKey}}" selectedAttribute="active"></core-selector>

<div id="itemList" layout horizontal wrap>

        <template repeat="{{item, i in items}}">

            <div id="{{item.name}}">
                <entriesHeading name="{{item.name}}" horizontal layout center>
                    <div flex>{{item.name}}</div>
                    <paper-menu-button icon="more-vert" halign="right">
                        <paper-item label="Edit" on-tap="{{ itemEdit }}"></paper-item>
                        <paper-item label="Copy" on-tap="{{ itemCopy }}"></paper-item>
                        <paper-item label="Delete" on-tap="{{ itemDelete }}"></paper-item>
                    </paper-menu-button>
                </entriesHeading>
                <entriesContainer vertical layout>
                    *** container contents ***
                </entriesContainer>
            </div>

        </template>

</div>

关于如何避免与核心选择事件发生这种不必要的相互作用的任何建议?也许某种特定的听众(仅限于收听纸张下拉选择核心事件)?

2 个答案:

答案 0 :(得分:3)

paper-dropdown无法从任何地方接收事件,但在其自己的子树内。你必须提出一个jsbin或某种复制品,否则我必须建议你的诊断是不正确的。

您应该尝试弄清楚事件的进展情况,以确保您对系统有充分的了解。

话虽如此,另一种解决问题的方法是数据驱动而不是控制驱动。

IOW,最好对数据更改而不是事件做出反应。提供非常好的建议很难,因为我只能看到你申请的一小部分,但这里有一些建议:

你有

<paper-dropdown id="widthUnits" class="unitSelection" 
   selected="{{item.data.designWidth[1]}}" 
   on-core-select="{{ conditionUnitSelectionChanged }}" valueattr="label">

这个重要数据被引用为item.data.designWidth[1],这有点不幸。通常,人们想要考虑应用程序数据,以便您不使用这样的深层嵌套表达式。举个例子,如果您可以构建类似design-width-editor的用户界面并将其绑定到<design-width-editor designWidth="{{item.data.designWidth[1]}}">,那么您可以将design-width-editor中的逻辑放在designWidth处理并且不会处理item我需要了解dataobserve: { 'item.data.designWidth[1]`: 'designWidth1Changed' } 。这为您的数据结构提供了更大的灵活性,使您更容易思考。

无论如何,考虑到你的构造,你可以做的一件事是直接观察数据:

designWidth1Changed()

现在,您可以实施{{1}}来执行所需的操作。这里的关键点是您不再依赖于任何特定的UI来修改designWidth数据。您可以随意替换该UI;重要的是,如果价值发生变化,就会采取一些行动。

答案 1 :(得分:1)

斯科特让我走上正轨。在前面评论中描述的一些重构之后,我使用了async来帮助观察者在我不想要的时候执行(例如当模型item对象改变时...因此所有观察到的属性)。以下是上述主机元素中用于解决最终问题的一些脚本代码的示例:

ignoreChanges: null,

observe: {
   'item.data.designWidth[0]': 'designWidthValueChanged',
   'item.data.designWidth[1]': 'designWidthUnitChanged',
}

designWidthValueChanged: function(oldVal, newVal) {
    if (!this.ignoreChanges) {
        // send update of width value input via ajax
        this.ajaxUpdateCondition("designWidth", newVal, this.item.data.designWidth[1]);
    }
},

designWidthUnitChanged: function(oldVal, newVal) {
    if (!this.ignoreChanges) {
        // send update of width unit selection via ajax
        this.ajaxUpdateCondition("designWidth", this.item.data.designWidth[0], newVal);
    }
},

itemKeyChanged: function(oldVal, newVal) {
    // itemKey is a published attribute that is 2 way bound to a parent element (where item selection occurs from a collection)                
    this.toggleIgnoreChanges(true); //set flag to ignore changes to observed values while item object switches 
    this.item = this.items[newVal]; //point to the correct/selected item in the collection (items is published attribute of this element)
    this.async(this.toggleIgnoreChanges);  //reset flag after observe functions have executed
},

toggleIgnoreChanges: function(flagstatus) {
    this.ignoreChanges = flagstatus || !this.ignoreChanges;
}
相关问题