2

我遇到了一个问题,即纸张下拉元素的 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);
      }
},

这里是核心选择器和相关代码,它们是应用程序中完全不同元素的一部分。仅供参考,SelectedItemKey在所涉及的两个元素中都受到聚合物“改变”事件的关注……如果这很重要的话。

<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>

关于如何避免与核心选择事件发生这种不必要的相互作用的任何建议?也许是某种特定的监听器(仅限于监听 paper-dropdown(s) core-select 事件)?

4

2 回答 2

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]. 通常,人们希望对应用程序数据进行分解,这样您就不会使用这样的深度嵌套表达式。举个例子,如果您可以构建一个类似的 UIdesign-width-editor并将其绑定到,<design-width-editor designWidth="{{item.data.designWidth[1]}}">那么您可以将逻辑放入其中design-width-editor,只处理designWidth而不需要了解itemor data。这为您的数据结构提供了更大的灵活性,并且更容易思考。

无论如何,鉴于您的结构,您可以做的一件事是直接观察数据:

observe: {
  'item.data.designWidth[1]`: 'designWidth1Changed'
}

现在您可以实施designWidth1Changed()以采取所需的行动。这里的关键是您不再依赖任何特定的 UI 来修改 designWidth 数据。您可以随意更换该 UI;重要的是,如果值发生变化,就会采取一些行动。

于 2014-09-18T03:06:48.717 回答
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;
}
于 2014-09-19T23:25:08.997 回答