【问题标题】:No communication between custom Polymer components自定义 Polymer 组件之间没有通信
【发布时间】:2015-10-07 20:09:20
【问题描述】:

我编写了一个自定义 Polymer 组件,其中包含多个较小的自定义组件,这些组件针对整个流程的一个特定步骤而设计。 这些元素应该请求特定的输入参数,并且每个步骤都建立在前面的步骤之上。最后一个组件包含从 API 检索到的结果,该 API 接受从第一步收集的输入。

我的问题是我无法从一个组件到下一个组件获取信息。我几乎在我使用的每个组件中都有这个问题,所以我怀疑我想要这样做的方式是问题。

第一个问题是我需要从 API 中检索一个可能性列表,并将该列表显示在多个子组件的下拉列表中。 我将此列表放在 Polymer 属性中,但不会触发自动绑定,并且数据更改未正确传播到子组件(如果有的话)。我定义了一些可以正常获取数据的 iron-ajax 元素,并且有一个包含需要这些 iron-ajax 元素输出的子组件的模板。

<template>
    <iron-ajax auto url="{{typesURL}}" handle-as="json"
      on-response="handleTypesResponse"></iron-ajax>
    <!-- more iron-ajax elements -->

    <section id="activities">
      <template is="dom-repeat" items="{{activities}}" as="activity">
        <my-activity activity="{{activity}}"
                      types="{{types}}" />
      </template>
    </section>
    <!-- more classic html elements -->
</template>

我的 url 很简单,它可以很好地转换为数组,但是如果我向活动数组中添加项目,活动中的 模板 不会重新加载和编辑。我怎么能做到这一点?

我面临的第二个问题是获取组件的“结果”。 我有一个表单,我希望用户指定时间。为此,我使用paper-time-picker。但是,选择时间后,并返回到底层Web组件时,时间不会更改。 这是定义对话框的代码:

<paper-dialog id="timeDialog" modal class="paper-time-picker-dialog" entry-animation="scale-up-animation" exit-animation="fade-out-animation">
  <h2>Start time <span>{{activity.name}}</span></h2>
  <paper-time-picker id="startTimePicker"></paper-time-picker>
  <div class="buttons">
    <paper-button dialog-dismiss>Cancel</paper-button>
    <paper-button dialog-confirm autofocus on-tap="confirmTime">OK</paper-button>
  </div>
</paper-dialog>

Polymer 属性下面定义的这些函数既显示又检索对话框和结果:

  showAttachedDialog: function (id) {
    var button = this.$$(id);
    if (!button.hasAttribute('data-dialog')) {
      return;
    }

    var dialogId = '#' + button.getAttribute('data-dialog');
    var dialog = this.$$(dialogId);
    if (dialog) {
      dialog.open();
    }
  },
  confirmTime: function () {
    this.activity['time'] = this.$$('#timePicker').time;
    this.notifyPath('activity.time', this.activity.time);

    console.log(this.activity);
    console.log("time activity: " + this.activity.time);
  },

控制台输出变为空(如“时间活动:”)。有谁看到我做错了什么?如果您需要了解我在这里可能遗漏的内容,请务必询问更多信息。 谢谢。

【问题讨论】:

    标签: javascript html polymer polymer-1.0


    【解决方案1】:

    关于活动 - 你应该使用 Polymer 的推送、弹出等,请参阅 https://www.polymer-project.org/1.0/docs/devguide/templates.html#dom-repeat。或者手动调用 notifyPath。这有效:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>xxz</title>
        <script src="./bower_components/webcomponentsjs/webcomponents.js"></script>
    
        <link rel="import" href="./bower_components/polymer/polymer.html">
    
    
        <link rel="import" href="bower_components/paper-time-picker/paper-time-picker.html">
        <link rel="import" href="bower_components/paper-input/paper-input.html">
        <link rel="import" href="bower_components/paper-button/paper-button.html">
        <link rel="import" href="bower_components/paper-dialog/paper-dialog.html">
        <link rel="import" href="bower_components/neon-animation/animations/scale-up-animation.html">
        <link rel="import" href="bower_components/neon-animation/animations/fade-out-animation.html">
    
        <dom-module id="my-activity">
            <style>
                :host{
                    display: block;
                }
            </style>
            <template>
                Activity <span>{{activity.name}}</span>
                <paper-button on-click=showAttachedDialog>Time dialog <span>{{activity.time}}</span></paper-button>
    
                <paper-dialog id="timeDialog" modal class="paper-time-picker-dialog" entry-animation="scale-up-animation" exit-animation="fade-out-animation">
                    <h2>Activity name <span>{{activity.name}}</span></h2>
    
                    <!-- from https://github.com/bendavis78/paper-time-picker -->
                    <paper-time-picker id="startTimePicker"></paper-time-picker>
                    <!--unfortunately  paper-time-picker is not a iron-input (is="iron-input") so you can't jut bind to its value-->
                    <!--start time: <paper-input id="time" value="{{activity.time}}"></paper-input>-->
    
                    <div class="buttons">
                        <paper-button dialog-dismiss>Cancel</paper-button>
                        <paper-button dialog-confirm autofocus on-tap="confirmTime">OK</paper-button>
                    </div>
                </paper-dialog>
            </template>
            <script>
                HTMLImports.whenReady(function () {
                    Polymer({
                        is: "my-activity",
                        activity: Object,
                        listeners: {
                            'startTimePicker.time-changed': '_onTimeChanged'
                        },
    
                        //this is not needed if time is copied in confirmTime
                        _onTimeChanged: function(){
                            if (this.activity) {//first event is fired before activity is set
                                console.log("time activity: " + this.activity.time+' startTimePicker.time='+ this.$.startTimePicker.time);
                                this.activity.time = this.$.startTimePicker.time;
                            }
                        },
    
                        showAttachedDialog: function (event /*id*/) {
    //                        that's I can't comprehend
    //                        var button = this.$$(id);
    //                        if (!button.hasAttribute('data-dialog')) {
    //                            return;
    //                        }
    //
    //                        var dialogId = '#' + button.getAttribute('data-dialog');
    //                        var dialog = this.$$(dialogId);
    //                        if (dialog) {
    //                            dialog.open();
    //                        }
                            this.$.timeDialog.open();
                        },
                        confirmTime: function () {
    //                        this.activity['time'] = this.$$('#timePicker').time;
    //                        this.notifyPath('activity.time', this.activity.time);
    
                            this.activity.time = this.$.startTimePicker.time;
                            console.log("time activity: " + this.activity.time+' startTimePicker.time='+ this.$.startTimePicker.time);
    
                        }
                    })
    
                });
            </script>
        </dom-module>
    
        <dom-module id="my-element">
            <template>
    
                <paper-button on-click=handleTypesResponse>Kinda call ajax</paper-button>
    
                <section>
                    <template is="dom-repeat" items="{{activities}}" as="activity">
                        <my-activity activity="{{activity}}" />
                    </template>
                </section>
    
            </template>
            <script>
                HTMLImports.whenReady(function () {
                    Polymer({
                        is: "my-element",
    
                        handleTypesResponse: function () {
                            this.splice('activities', 0, 3);
                            for (var i = 0; i < 10; i++) {
                                console.log('i=' + i);
                                this.push('activities', {name: 'name'+i, time: new Date()});
    
                            }
                        },
    
                        ready: function() {
                            this.activities = [];
                            this.push('activities', {name: 'name XXX', time: new Date()});
                            this.push('activities', {name: 'name YY', time: new Date()});
                            this.push('activities', {name: 'name ZZ', time: new Date()});
                        }
                    });
                });
            </script>
    
        </dom-module>
    
    
    </head>
    <body>
    
    <my-element></my-element>
    
    
    </body>
    </html>
    

    【讨论】:

    • 这正是我用来进行时间选择的选择器。我会试一试 - 没有尝试在创建活动时初始化所有属性 - 会尝试并报告。
    • 附录:我以前保存的结果错误。我不得不做this.activity.time = dialog.time。但是 Push 和 notifyPath 并没有执行他们宣传的功能。我之前也尝试过它们,但它们从未为我工作过。我应该注意什么以确保它可以按设计工作?
    • 抱歉,我原以为纸时间选择器是铁输入,但它不是。所以你应该手动更新模型数据。如果您需要就地验证或“实时”的东西,您可以为此使用侦听器。
    猜你喜欢
    • 2014-11-19
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    相关资源
    最近更新 更多