将函数传递给模具组件



是否可以将函数传递给stencilJs组件?

像这样:

@Prop() okFunc: () => void;

我有一个模态,想要在模态页脚中单击的Ok按钮上动态调用传递的函数,就像普通 HTML 按钮上的onClick一样。

是的,你可以。这只是一个普通的@Prop()声明,在多伦多证券交易所发挥得非常好。然而。。。

如另一个答案和评论中所述,如果您在纯 ol' HTML 中使用 Stencil 组件,您将无法使用 Stencil 的属性-prop 绑定通过 HTML 属性将函数(或任何非标量值)传递给 prop。

使用 DOM API

这意味着如果你想附加事件或将函数道具传递给 Stencil 组件,你必须与 DOM 交互。一旦您的组件进入 DOM,与任何其他自定义元素相比,它实际上没有什么特别之处。

如果没有 JSX 或其他模板 DSL(例如 Angular),您将需要使用 JavaScript DOM API 附加事件并设置函数或对象引用属性:

const componentInstance = document.querySelector('my-stencil-component')
// This works and will trigger a rerender (as expected for a prop change)
componentInstance.someFunc = (...) => { ... }
// This works for any event, including custom events fired from Stencil's EventEmitter
componentInstance.addEventListener('myCustomEvent', (event: MyCustomEvent) => { ... })

如果出于某种原因绝对必须在HTML 文档中执行此操作:

<my-stencil-component ... >...</my-stencil-component>
<script>
var componentInstance = document.currentScript.previousElementSibling
componentInstance.someFunc = function(...) { ... }
</script>

为什么我必须这样做?

重要的是要意识到Properties ≠ Attributes.Props 是 JavaScript 属性,在本例中是表示元素的 DOM 对象的属性。属性是 XML 属性,尽管 HTML 属性具有一些独特的特征,并且行为与典型的 XML 略有不同。

在可能的情况下,模板会自动将HTML属性"绑定"到属性 - 特别是标量值(booleannumberstring)。对象引用(因此不能将函数)用作属性的值。从技术上讲,只有strings可以是属性值,但是当您指定@Prop()的类型时,Stencil足够聪明,可以将string转换为其他其他标量类型(booleannumber)。

<小时 />

其他解决方案

我为我的团队开发了一个解决方案,使用MutationObserver将包含 JSON 的属性绑定到 Stencil 属性。它基本上监视一个特殊的属性bind-json,然后将以json-开头的属性映射到相应的驼峰案例DOM属性上。用法如下所示:

<my-stencil-component
bind-json
json-prop-name='{ "key": "value" }'>
</my-stencil-component>

有了MutationObserver,这与

const componentInstance = document.querySelector('my-stencil-component')
componentInstance.propName = JSON.parse(componentInstance.getAttribute('json-prop-name'))

但是,对于在纯HTML中绑定函数确实没有令人满意的解决方案。如果没有像另一条评论中描述的那样eval某种丑陋的黑客,它真的无法完成。这不仅会污染组件的 API,而且由于各种其他原因而存在问题,我不会在这里讨论,它的使用会在几乎任何现代安全检查中自动使您的应用程序失败。

在我们的故事书故事中,我们将回调函数定义绑定到window,并使用<script>标签和document.currentScriptquerySelector将函数属性和事件绑定传递给组件实例:

const MyStory = ({ ... }) => {
window.myStoryFunc = () => { ... }
window.myStoryClickHandler = () => { ... }
return `
<my-stencil-component ... >...</my-stencil-component>
<script>
const componentInstance = document.currentScript.previousElementSibling
componentInstance.someFunc = window.myStoryFunc
componentInstance.addEventListener('click', window.myStoryClickHandler)
</script>
`
}

您可以向任何组件添加@Prop() someFunc: Function并从外部传递它,例如<any-component someFunc={() => console.log('coming from the outside')} />

在任何组件中,只需检查if (this.someFunc) { this.someFunc() }

相关内容

  • 没有找到相关文章

最新更新