如何在Chrome应用程序中使用Polymer构建侧导航的示例?

时间:2016-07-30 06:47:37

标签: polymer google-chrome-app

我正在构建Chrome应用。我想使用Polymer构建UI。我喜欢它们在example web app in the docs中显示的侧面导航:左侧导航栏中的项目可以更改主窗口中的内容。

我正在努力解决Chrome应用程序的限制问题。应用程序面临严格的内容安全策略(CSP),禁止使用eval,内联脚本和window.history操作。

我在过去的几个小时里取得了一些进展,但遇到了很多问题。从他们的演示代码开始,我可以让应用程序呈现侧面导航栏而不是内容卡。我使用的是vulcanizecrisper,但仍无法使其正常运行。如果它不是404(如果我导入它们,为什么要加载文件?),那就是可疑"拒绝将字符串评估为Javascript"警告似乎与Polymer库本身看似无关紧要的行var noop = Function();有关。

是否有人知道他们可以指向我的基础知识,Chrome应用程序友好的这种架构示例?它似乎非常基本,但它证明是困难的。

1 个答案:

答案 0 :(得分:2)

嗯,第2天的挣扎导致了一些适度的成功。我现在可以在Chrome应用中显示他们的demo sidebar navigation app。有几件事需要改变。

首先,Chrome应用不支持window.history系列API。因此,他们用于路由的<app-location>标记不起作用,因为它依赖于位置并显然利用window.history API。相反,我删除了该标签,并以某种方式成功地使用数据绑定作为路由。以下是my-app.html的相关部分。更改的主要内容是删除<app-location>(为了清楚起见,我在这里留下了评论),并将selected数据绑定属性从[[page]]更改为{{page}}。花括号允许双向绑定。我相信必须允许<iron-selector>元素将page变量发送到<iron-pages>元素。

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

<app-drawer-layout fullbleed>

  <!-- Drawer content -->
  <app-drawer>
    <app-toolbar>Menu</app-toolbar>
    <iron-selector selected="{{page}}" attr-for-selected="name" class="drawer-list" role="navigation">
      <a name="view1" >View One</a>
      <a name="view2" >View Two</a>
      <a name="view3" >View Three</a>
      <a name="new-view" href="/new-view">New View</a>
    </iron-selector>
  </app-drawer>

  <!-- Main content -->
  <app-header-layout has-scrolling-region>

    <app-header condenses reveals effects="waterfall">
      <app-toolbar>
        <paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
        <div title>My App</div>
      </app-toolbar>
    </app-header>

    <iron-pages role="main" selected="{{page}}" attr-for-selected="name">
      <my-view1 name="view1"></my-view1>
      <my-view2 name="view2"></my-view2>
      <my-view3 name="view3"></my-view3>
      <my-new-view name="new-view"></my-new-view>
    </iron-pages>

  </app-header-layout>

</app-drawer-layout>

在下面显示的vulcanizecrisper流程之后,这允许在加载为Chrome应用时显示导航栏。但是,页面本身(由<iron-pages>控制)不会加载。这是因为演示通过动态执行HTML导入来尝试用户友好。由于路径问题(以及可能的网址加载限制 - 我不确定),这会混淆Chrome应用。相反,我们将手动导入它们。这将使vulcanize发挥其魔力。将以下行添加到src/my-app.html

顶部的其余导入中
<link rel="import" href="my-view1.html">
<link rel="import" href="my-view2.html">
<link rel="import" href="my-view3.html">
<link rel="import" href="my-new-view.html">

最后,从observer: '_pageChanged'的脚本部分删除_pageChangedsrv/my-app.html函数。

我们越来越近了。

Chrome Apps具有严格的内容安全策略,可阻止内联脚本(即<script>标记中的脚本)的执行。 Polymer大量使用内联脚本,因此框架作者提供了一种解决此问题的工具。

vulcanize遍历HTML导入语句以尝试减少网络负载。 crisper提取所有内联脚本并将其添加到具有<script>属性的单个src标记中,以便在Chrome应用中执行。以下行将现有的index.html替换为Chrome应用的一个安全保护。 (注意替换,所以请确保先复制原始index.html。)

vulcanize --inline-scripts --inline-css index.html | crisper --html index.html --js index.js

现在我们有index.html没有可以呈现为Chrome应用的任何内联脚本。截至2016-07-30,仍存在两个问题。第一个是Polymer尝试注册服务工作者。打开index.js并移除serviceWorker.register电话。其次,在_boundEffect中找到index.js的定义。出于某种原因,Chrome应用认为var noop = Function();需要eval,并且它不会执行它。将此行替换为var noop = () => {}。这基本上是相同的,但由于某些原因Chrome Apps允许它。

完成所有这些操作后,在Chrome应用中加载index.html并演示。

好哇。