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

Example of how to architect side-navigation using Polymer in a Chrome App?

我正在构建一个 Chrome 应用程序。我想使用 Polymer. I like the side navigation they show in the example web app in the docs 构造 UI:一个左导航栏的项目,它改变了主 window.

中的内容

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

我在过去的几个小时里取得了一些进展,但是 运行 遇到了很多问题。从他们的演示代码开始,我可以让应用程序呈现侧边导航栏而不是内容卡片。我正在使用 vulcanizecrisper,但仍然无法正常工作。如果它不是 404(如果我正在导入它们,为什么它会加载文件?),这是一个可疑的 "Refused to evaluate a string as Javascript" 警告,似乎与 Polymer 库本身中看似无害的行 var noop = Function(); 有关。

有谁知道基本的、Chrome 这种架构的应用程序友好示例,他们可以向我指出吗?这看起来很基础,但事实证明它很难。

好吧,第 2 天的挣扎取得了一定的成功。我现在可以在 Chrome 应用程序中显示他们的 demo sidebar navigation app。有几件事必须改变。

首先,API 的 window.history 系列在 Chrome 应用程序上不可用。结果,他们用于路由的 <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 导入来对用户友好。由于路径问题(可能 URL 加载限制——我不确定),这会混淆 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">

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

我们快到了。

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

vulcanize walks HTML import statements to try and reduce network loads. crisper 提取所有内联脚本并将它们分类为具有 src 属性的单个 <script> 标记,允许它在 Chrome 应用程序中执行。以下行将现有的 index.html 替换为 Chrome 应用程序的一个保险箱。 (请注意 REPLACES,因此请务必先复制原件 index.html。)

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

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

完成这一切后,在您的 Chrome 应用程序中加载 index.html,演示就可以运行了。

万岁。