首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同构hyperHTML元件不入线

同构hyperHTML元件不入线
EN

Stack Overflow用户
提问于 2018-04-03 20:09:49
回答 1查看 254关注 0票数 0

我有以下两个组成部分:

代码语言:javascript
复制
// component.js
// imports ...

function ListItem(item) {
  const html = wire(item)

  function render() {
    return html`<li>${item.foo}</li>`
  }

  return render()
}

function List(items) {
  const html = wire(items)

  function render() {
    return html`<ul>${items.map(ListItem)}</ul>`
  }

  return render()
}

我想把它们放在一个在客户端和服务器之间共享的模块中。但是,据我所知,虽然API与viperHTML模块基本相同,但在服务器上,我必须从hyperHTML模块导入函数,而在客户机上,我必须使用hyperHTML模块。因此,我不能只在共享模块的顶部导入函数,而是必须传递到调用站点上的组件。

这样做,我的同构分量看起来如下所示:

代码语言:javascript
复制
// component.js

function ListItem(html, item) {
  //const html = wire(item) // <- NOTE

  function render() {
    return html`<li>${item.foo}</li>`
  }

  return render()
}

function List(html, itemHtmls /* :( tried to be consistent */, items) {
  //const html = wire(items) // <- NOTE

  function render() {
    return html`<ul>${items.map(function(item, idx) {
      return ListItem(itemHtmls[idx], item)
    })}</ul>`
  }

  return render()
}

从服务器调用组件:

代码语言:javascript
复制
// server.js
const {hyper, wire, bind, Component} = require('viperhtml')

const items = [{foo: 'bar'}, {foo: 'baz'}, {foo: 'xyz'}]
// wire for the list
const listWire = wire(items)
// wires for the children
const listItemWires = items.map(wire)

const renderedMarkup = List(listWire, listItemWires, items)

从浏览器调用将完全相同,期望采用导入hyperhtml的方式:

代码语言:javascript
复制
// client.js
import {hyper, wire, bind, Component} from 'hyperhtml/esm'

然而,编写这样的代码感觉很不舒服,因为我有一种感觉,那就是电线()调用的结果应该存在于组件实例中。是否有更好的方法来编写同构的超HTML/viperHTML组件?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-04 09:50:32

更新现在有一个由超形模块提供的解决方案。

理想的情况是,您只需要依赖viperhtml,而这反过来又会自动地引入hyperhtml,正如index.js文件所看到的那样。

此时,客户端绑定程序应该(如果有能力的话)为您摇动未使用的代码,但是您有一个非常好的点,这一点还不是很清楚。

我也不完全确定,如果像typeof document === "object"这样的检查总是正确的,并且只针对浏览器,那么绑定器是否可以那么聪明。

一种尝试的方法就是

代码语言:javascript
复制
import {hyper, wire, bind, Component} from 'viperhtml'

在客户端,也希望它不会带来viperHTML依赖,一旦捆绑‘,因为有很多东西,你不需要在浏览器上。

我有一种感觉,电线()调用的结果应该存在于组件实例中。

您可以使用viper.Component简化您的组件,这样您就有了render() { return this.html... },并且您忘记了传递连接的问题,但我同意您的意见,还有改进的余地。

此时,您只需解析要在一个地方导入哪个Component,并定义在b客户机和服务器上工作的可移植组件。

这基本上就是轻量级Component存在的原因,它让您可以自由地关注组件,而无需考虑连接的内容、方式和/或地点(如果客户机/服务器)。

我本打算给您举一个例子,但是您将内容与项目联系起来(这是正确的),这让我认为当前的组件也可以改进,因此对于您的情况,我创造了一张罚单作为后续行动也是可以改进的,我希望我能尽快有更好的示例(用于组件)。

编辑

我已经更新了库,允许您使用代码笔示例创建能够使用/接收数据/项的组件。

代码语言:javascript
复制
class ListItem extends Component {
  constructor(item) {
    super().item = item;
  }
  render() {
    return this.html`<li>${this.item.foo}</li>`;
  }
}

class List extends Component {
  constructor(items) {
    super().items = items;
  }
  render() {
    return this.html`
    <ul>${this.items.map(item => ListItem.for(item))}</ul>`;
  }
}

当您使用组件时,您要确保这些组件在客户机/服务器之间是可移植的。

目前唯一的问题是找出检索Component类的最佳方法。

一种可能的解决方案是将此类的导出集中在单个入口点。

然而,问题的关键是NodeJS还不兼容ESM模块,浏览器也不兼容CommonJS,所以我没有最好的答案,因为我不知道您是否/如何捆绑您的代码。

理想情况下,您应该使用CommonJS,它在NodeJS中是开箱即用的,并且与每个浏览器绑定器兼容,但是您需要在每次构建时区分导出该Component或任何其他超/viperHTML相关实用程序的文件。

我希望我已经给了你足够的提示,以最终解决目前的限制。

抱歉,如果我现在没有更好的答案。我以前使用过外部呈现,但它可能不是处理更复杂的结构/组件的最方便的方法。

你可以像这样写那些函数

代码语言:javascript
复制
function ListItem(item) {
  return wire(item)`<li>${item.foo}</li>`;
}

function List(items) {
  return wire(items)`<ul>${items.map(ListItem)}</ul>`;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49638355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档