简体   繁体   English

使用代理访问自定义元素的数据集

[英]Using a proxy to access the dataset of a custom element

Imagine this trivial custom element: 想象一下这个简单的自定义元素:

<my-el data-cute-number="7" id="foo"></my-el>

document.getElementById('foo').dataset.cuteNumber , as expected, returns the String "7". document.getElementById('foo').dataset.cuteNumber ,如预期的那样,返回字符串“7”。 I would like to create a proxy for accessing dataset properties that does the casting to Number for me because I'm using the property alot in the component code and would like to avoid repeatedly having to cast it manually every time I access it. 我想创建一个代理来访问数据集属性,为我执行转换为Number ,因为我在组件代码中使用了很多属性,并希望每次访问时都不必反复手动转换它。 I also do not want to create an additional getter for a new property (eg get cuteNumber() { return Number(this.dataset.cuteNumber); } ) on the component itself since I will have to do all the synchronisation manually then (since I'd also need a setter), make sure I avoid infinite update loops, etc. 我也不想为新属性创建额外的getter(例如, get cuteNumber() { return Number(this.dataset.cuteNumber); } )组件本身,因为我必须手动完成所有同步(因为我还需要一个setter),确保我避免无限更新循环等。

As I understand proxies, this is exactly where a proxy will help me. 据我了解代理,这正是代理将帮助我的地方。

 customElements.define('my-el', class extends HTMLElement { constructor() { super(); const proxy = new Proxy(this.dataset, { get: function(context, prop, receiver) { console.log(`Proxy getter executing for ${prop}`); switch (prop) { case 'cuteNumber': return Number(context[prop]); break; default: return context[prop]; } } }); } }) console.log(typeof document.getElementById('foo').dataset.cuteNumber); 
 <my-el data-cute-number="7" id="foo"></my-el> 

This is where I'm stuck. 这就是我被困住的地方。

Accessing the dataset currently does not trigger the proxy (the inner console.log doesn't show up). 访问dataset当前不会触发代理(内部console.log不会显示)。

Can anyone point me in the right direction? 谁能指出我正确的方向? Is it even possible to proxy the dataset of an element? 是否可以代理元素的dataset

Creating a proxy does not mutate the target object, it doesn't become a proxy. 创建代理不会改变目标对象,也不会成为代理。 The proxy is a new object that wraps around the target. 代理是一个包裹目标的新对象。 In your code, you are just throwing away the proxy and never use it - the .dataset property is unaffected. 在您的代码中,您只是丢弃proxy并且从不使用它 - .dataset属性不受影响。 You'll want to either overwrite it or create a new property: 您要覆盖它或创建新属性:

 customElements.define('my-el', class extends HTMLElement { get dataset() { //^^^^^^^^^^^^^ return new Proxy(super.dataset, { // ^^^^^^ get: function(target, prop, receiver) { console.log(`Proxy getter executing for ${prop}`); if (prop == 'cuteNumber') return Number(target.cuteNumber); return Reflect.get(target, prop, receiver); } }); } }); console.log(typeof document.getElementById('foo').dataset.cuteNumber); 
 <my-el data-cute-number="7" id="foo"></my-el> 
 customElements.define('my-el', class extends HTMLElement { constructor() { super(); this.numberdata = new Proxy(this.dataset, { // ^^^^^^^^^^^^^^^^^ get: function(target, prop, receiver) { return Number(target[prop]); } }); } }); console.log(typeof document.getElementById('foo').numberdata.cuteNumber); 
 <my-el data-cute-number="7" id="foo"></my-el> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM