Polymer 1.6和Polymer-cli,从自定义元素

时间:2016-06-30 17:12:44

标签: javascript html polymer polymer-cli

使用polymer-cli工具和购物车样板作为起点,我做了一个简单的模型来说明用例。

假设您的index.html文件包含“test-app.html”和匹配标记

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">

  <title>My App</title>

  <link rel="shortcut icon" sizes="32x32" href="/images/app-icon-32.png">

  <meta name="theme-color" content="#fff">
  <link rel="manifest" href="/manifest.json">

  <script>

    // setup Polymer options
    window.Polymer = {lazyRegister: true, dom: 'shadow'};

    // load webcomponents polyfills
    (function() {
      if ('registerElement' in document
          && 'import' in document.createElement('link')
          && 'content' in document.createElement('template')) {
        // browser has web components
      } else {
        // polyfill web components
        var e = document.createElement('script');
        e.src = '/bower_components/webcomponentsjs/webcomponents-lite.min.js';
        document.head.appendChild(e);
      }
    })();

    // load pre-caching service worker
    if ('serviceWorker' in navigator) {
      window.addEventListener('load', function() {
        navigator.serviceWorker.register('/service-worker.js');
      });
    }

  </script>

  <!-- <link rel="import" href="/src/bewi-app.html"> -->
  <link rel="import" href="/src/test-app.html">

  <style>

    body {
      margin: 0;
      font-family: 'Roboto', 'Noto', sans-serif;
      line-height: 1.5;
      min-height: 100vh;
      background-color: #eee;
    }

  </style>

</head>
<body>
  <span id="browser-sync-binding"></span>

  <test-app id="test"></test-app>

</body>
</html>

现在,假设test-app.html包含以下内容(再次仅仅是my-app.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/app-route/app-route.html">
<link rel="import" href="test-element.html">

<dom-module id="test-app">

  <template>

    <app-location route="{{route}}"></app-location>
    <app-route
        route="{{route}}"
        pattern="/:page"
        data="{{routeData}}"
        tail="{{subroute}}"></app-route>

        test-element is loaded bellow
        <test-element></test-element>
    <div>
    </div>
  </template>

  <script>

    Polymer({

      is: 'test-app',

      properties: {

        page: {
          type: String,
          reflectToAttribute: true,
          observer: '_pageChanged'
        },
        baseUrl: {
          type: String,
          value: '/'
        },
        siteUrl: {
          type: String,
          value: 'http://fqdn.local'
        }
      },

      observers: [
        '_routePageChanged(routeData.page)'
      ],

      _routePageChanged: function(page) {
        this.page = page || 'view1';
      },

      _pageChanged: function(page) {
        // load page import on demand.
        this.importHref(
          this.resolveUrl('my-' + page + '.html'), null, null, true);
      }

    });

  </script>

</dom-module>

现在,test-element.html

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

<dom-module id="test-element">
  <template>
    <div> I am a test </div>
  </template>

  <script>
  (function() {
    'use strict';

    Polymer({
      is: 'test-element',
      ready: function() {
        console.log('READY');
        console.log('find #test using document.querySelector', document.querySelector('#test')); // OK
        console.log('find #test .siteUrl using document.querySelector', document.querySelector('#test').siteUrl); // undefined
        console.log('find #test .siteUrl using Polymer.dom', Polymer.dom(document.querySelector('#test')).siteUrl); // undefined
        console.log('find #test .siteUrl using Polymer.dom().node', Polymer.dom(document.querySelector('#test')).node.siteUrl); // undefined
        console.log('find #test .siteUrl using Polymer.dom().properties', Polymer.dom(document.querySelector('#test')).node.properties); // {object} but, I'm guessing not the computed values of the properties

        // So, how may I access the #test app's "siteUrl" property from within a custom element?
      }
    });
  })();
  </script>
</dom-module>

所以,真正的问题是,test-element如何在主应用中访问属性“siteUrl”? 我打算将此变量设为readOnly,并从其他自定义元素访问它。 我更喜欢这种方法VS将siteUrl作为属性传递给test-element元素..

您怎么看?

1 个答案:

答案 0 :(得分:1)

通过元素传递信息的正确方法是使用Data Binding system,即“将siteUrl作为属性传递给test-elemet元素”

您将使用方括号完成围绕变量的只读要求,例如Property change notification and two-way binding中所述的此[[siteUrl]]

您可以在全球环境中设置变量,如您所说

<script>
  var myGlobalVar = 'is accessible in any element'

  Polymer({

    is: 'test-app',

    // ...

  });

</script>

您可以在每个元素中访问它。

但是,您可能不知道全局变量。在下面的链接中参考了为什么。