【问题标题】:Polymer paper-dropdown's core-select event fired by another element's core-selectorPolymer paper-dropdown 的 core-select 事件由另一个元素的 core-selector 触发
【发布时间】:2014-09-18 01:53:08
【问题描述】:

我遇到了一个问题,即 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);
      }
},

这里是核心选择器和相关代码,它们是应用程序中完全不同元素的一部分。仅供参考,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 事件)?

【问题讨论】:

  • 不看应用的整体结构就很难说。 core-select 事件是否可能正在冒泡并被您的纸张下拉列表中的 on-core-select 处理程序拾取?如果是这样,您可以在 #itemSelector 上触发事件时调用 stopPropagation()

标签: polymer paper-elements core-elements


【解决方案1】:

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 的 UI 并将其绑定到&lt;design-width-editor designWidth="{{item.data.designWidth[1]}}"&gt;,那么你可以将逻辑放在design-width-editor 中,它只处理designWidth 而不需要知道itemdata。这为您的数据结构提供了更大的灵活性,并且更容易思考。

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

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

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

【讨论】:

  • 如果在同一个元素中有多个 paper-dropdowns 实例(我在上面的例子中只展示了一个),并且每个 paper-dropdown 的选定属性都绑定到数组元素,如下所示这个单个示例(即{{item.data.designWidth[1]}} 用于第一个下拉菜单,而其他 item.data 属性用于元素中的其他)。如何指定 selectedChanged 事件?我尝试实现selectedChanged 聚合物功能,也尝试了itemChanged,当下拉选择更改时,两者都没有触发。
  • 对不起,我走得太快了,给你一些错误的信息。您的设置中没有 selectedChanged 可供收听。我将更新我的答案以使其更有意义。
  • 我听取了您的建议并重构了代码,构建了一个自定义 item-valueeditor 元素...一个通用复合元素,由一个 paper-input(用于值输入)和 paper-dropdown(用于单位选择))。比如item-valueeditor发布属性inputvalue绑定item.data.designWidth[0],属性inputunitvalue绑定item.data.designWidth[1]。这些特定的item.data 值随后由宿主元素单独观察。 The problem now is that the various observation functions fire when the selected item itself changes.
  • Continued... 是否有最佳实践模式或方法来防止或绕过观察到的功能,例如,当我第一次加载item 或用户选择了不同的item来自收藏?
  • 查看下面的代码...使用异步对我有利,以避免观察函数在我不希望它们运行时运行的问题。
【解决方案2】:

斯科特让我走上了正轨。在前面的 cmets 中描述的一些重构之后,我使用 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    相关资源
    最近更新 更多