Полимер: наблюдатель глобальная переменная

Я хочу создать элемент, который откроет всплывающее окно и отобразит сообщение пользователю. Я хочу, чтобы он был доступен любым видом из моей системы. Поэтому я создал глобальную переменную, которая будет отвечать за сохранение сообщений об ошибках. Я хочу знать, как всплывающий элемент может узнать, когда эта переменная изменилась. Я импортирую всплывающее окно в my-app.формат html.

app-data.формат html

<link rel="import" href="../../bower_components/polymer/polymer.html">

<dom-module id="app-data">
    <script>
      (function() {
        var instances = [];
        var vars = Object.create(Polymer.Base);
        Polymer({
            is: 'app-data',

            properties: {
                data: {
                    type: Object,
                    value: '',
                    notify: true,
                    readonly: false,
                    observer: '_data_changed'
                },
                key: String
            },
            created: function() {
                key = this.getAttribute('key');
                if (!key) {
                    console.log(this);
                    throw('app-data element requires key');
                }
                instances.push({key:key, instance:this});
            },
            detached: function() {
                key = this.getAttribute('key');
                var i = instances.indexOf({key:key, instance:this});
                if (i >= 0) {
                    instances.splice(i, 1);
                }
            },
            _data_changed: function(newvalue, oldvalue) {
                key = this.getAttribute('key');
                if (!key) {
                    throw('_data_changed: app-data element requires key');
                }
                vars.set(key, newvalue);
                // notify the instances with the correct key
                for (var i = 0; i < instances.length; i++) {
                    if (instances[i].key == key) {
                        instances[i].instance.notifyPath('data', newvalue);
                    }
                }
            }
        });
    }());
  </script>
</dom-module>

меню-perfil.формат html

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/app-route/app-location.html">
<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="../../bower_components/iron-localstorage/iron-localstorage.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="app-data.html">

<dom-module id="menu-perfil">
  <template>
    <style>
      .user-info {
        padding: 20px;
      }
      .user-info .form-buttons {
        margin-top: 10px;
      }
    </style>

    <app-data id="idpopuphandler" key="popuphandler"></app-data>
    <iron-localstorage name="user-storage" value="{{storedUser}}"></iron-localstorage>

    <iron-ajax
       id="registerLoginAjax"
       method="post"
       content-type="application/json"
       handle-as="json"
       on-response="handleUserResponse"
       on-error="handleUserError"></iron-ajax>

    <div class="user-info">
      <div id="unauthenticated" hidden$="[[storedUser.loggedin]]">
        <h2>Log in</h2>

        <paper-input-container>
          <label>Usuário</label>
          <input is="iron-input" id="username" type="text" bind-value="{{formData.nome}}">
        </paper-input-container>
        <paper-input-container>
          <label>Senha</label>
          <input is="iron-input" id="password" type="password" bind-value="{{formData.senha}}">
        </paper-input-container>
        <div class="form-buttons">
          <paper-button raised class="primary" on-tap="postLogin">Log In</paper-button>
        </div>
      </div>
    </div>
  </template>
  <script>
    (function() {
        Polymer({
          is: 'menu-perfil',
          properties: {
            formData: {
              type: Object,
              value: {}
            },
            storedUser: Object,
            error: String
          },
          _setReqBody: function() {
            this.$.registerLoginAjax.body = this.formData;
          },
          postLogin: function() {
            this.$.registerLoginAjax.url = '/services/session/login';
            this._setReqBody();
            this.$.registerLoginAjax.generateRequest();
          },
          handleUserResponse: function(event) {
            var response = event.detail.response;
            console.log(response);
            if (response.token) {
              this.error = '';
              this.storedUser = {
                name: this.formData.nome,
                token: response.token,
                loggedin: true
              };
            } else if (response.erro) {
              this.error = response.erro[0].message;
            }
            // reset form data
            this.formData = {};
          },
          handleUserError: function(event) {
              var errorArray = [];
              var messageObject = {};
              messageObject.message = 'Erro interno';
              errorArray.push(messageObject);
              this.$.idpopuphandler.data = errorArray;
          }
        });
    })();
  </script>
</dom-module>

всплывающее сообщение.формат html

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html" />
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
<link rel="import" href="app-data.html">

<dom-module id="popup-message">
  <template>

    <app-data id="idpopuphandler" key="popuphandler"></app-data>

    <paper-dialog id="idpopup">
      <template is="dom-repeat" items="[[error]]">
        <p>[[item.message]]</p>
      </template>

      <paper-button dialog-dismiss>Ok</paper-button>
    </paper-dialog>
  </template>
  <script>
    (function() {
        Polymer({
          is: 'popup-message',
          properties: {
            error: {
              type: Array,
              observer: '_errorMessageChange'
            }
          },

          observers: [
            '_errorMessageChange(this.$.idpopuphandler.data)'
          ],

          _errorMessageChange: function(listMessage) {
            console.log(listMessage);
            if (listMessage.length > 0) {
              this.error = listMessage;
              this.$.idpopup.toggle();
            }
          }
        });
    })();
  </script>
</dom-module>

1 ответ

  1. Я изменяю тип переменной. От массива до логического.

    всплывающее сообщение.формат html

    <link rel="import" href="../../bower_components/polymer/polymer.html">
    <link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html" />
    <link rel="import" href="../../bower_components/paper-button/paper-button.html">
    <link rel="import" href="app-data.html">
    
    <dom-module id="popup-message">
      <template>
    
        <app-data id="idpopuphandler" key="popuphandler" data="{{popuphandler}}"></app-data>
        <app-data id="idpopupdata" key="popupdata"></app-data>
    
        <paper-dialog id="idpopup">
          <template is="dom-repeat" items="[[messages]]">
    -        <p>[[item.message]]</p>
    -      </template>
    
          <paper-button dialog-dismiss>Ok</paper-button>
        </paper-dialog>
      </template>
      <script>
        (function() {
            Polymer({
              is: 'popup-message',
              properties: {
                messages: Array
              },
    
              observers: [
                '_errorMessageChange(popuphandler)'
              ],
    
              _errorMessageChange: function(handler) {
                var vMessages = this.$.idpopupdata.data;
                if (typeof vMessages !== 'undefined' && vMessages.length > 0) {
                  this.messages = vMessages;
                  this.$.idpopup.toggle();
                }
              }
            });
        })();
      </script>
    </dom-module>
    

    меню-perfil.формат html

    <link rel="import" href="../../bower_components/polymer/polymer.html">
    <link rel="import" href="../../bower_components/app-route/app-location.html">
    <link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
    <link rel="import" href="../../bower_components/iron-localstorage/iron-localstorage.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="app-data.html">
    
    <dom-module id="menu-perfil">
      <template>
        <style>
          .user-info {
            padding: 20px;
          }
          .user-info .form-buttons {
            margin-top: 10px;
          }
        </style>
    
        <app-data id="idpopuphandler" key="popuphandler"></app-data>
        <app-data id="idpopupdata" key="popupdata"></app-data>
        <iron-localstorage name="user-storage" value="{{storedUser}}"></iron-localstorage>
    
        <iron-ajax
           id="registerLoginAjax"
           method="post"
           content-type="application/json"
           handle-as="json"
           on-response="handleUserResponse"
           on-error="handleUserError"></iron-ajax>
    
        <div class="user-info">
          <div id="unauthenticated" hidden$="[[storedUser.loggedin]]">
            <h2>Log in</h2>
    
            <paper-input-container>
              <label>Usuário</label>
              <input is="iron-input" id="username" type="text" bind-value="{{formData.nome}}">
            </paper-input-container>
            <paper-input-container>
              <label>Senha</label>
              <input is="iron-input" id="password" type="password" bind-value="{{formData.senha}}">
            </paper-input-container>
            <div class="form-buttons">
              <paper-button raised class="primary" on-tap="postLogin">Log In</paper-button>
            </div>
          </div>
        </div>
      </template>
      <script>
        (function() {
            Polymer({
              is: 'menu-perfil',
              properties: {
                formData: {
                  type: Object,
                  value: {}
                },
                storedUser: Object,
                error: String
              },
              _setReqBody: function() {
                this.$.registerLoginAjax.body = this.formData;
              },
              postLogin: function() {
                this.$.registerLoginAjax.url = '/services/session/login';
                this._setReqBody();
                this.$.registerLoginAjax.generateRequest();
              },
              handleUserResponse: function(event) {
                var response = event.detail.response;
                if (response.token) {
                  this.error = '';
                  this.storedUser = {
                    name: this.formData.nome,
                    token: response.token,
                    loggedin: true
                  };
                  // reset form data
                  this.formData = {};
                } else if (response.erro) {
                  this.$.idpopupdata.data = response.erro;
                  if (typeof this.$.idpopuphandler.data === 'undefined') {
                    this.$.idpopuphandler.data = true;
                  }
                  this.$.idpopuphandler.data = ! this.$.idpopuphandler.data;
                }
              },
              handleUserError: function(event) {
                this.$.idpopupdata.data = [{'message' : 'Erro Interno 1'}, {'message' : 'Erro interno 2'}];
                if (typeof this.$.idpopuphandler.data === 'undefined') {
                  this.$.idpopuphandler.data = true;
                }
                this.$.idpopuphandler.data = ! this.$.idpopuphandler.data;
              }
            });
        })();
      </script>
    </dom-module>