无法使用代理捕获对 customElements 的访问器调用?
Unable to trap accessor calls on customElements using Proxy?
我正在使用 customElements.define 注册一些自定义元素,并希望在成员访问器上自动设置陷阱,以便我可以在它们发生变化时发出事件
class State extends HTMLElement {
public someValue = 1;
public constructor() {
super();
console.log('State constructor');
}
}
const oProxy = new Proxy(State, {
get(target, prop: string) {
console.log(`GET trap ${prop}`);
return Reflect.get(target, prop);
},
set(target, prop: string, value: any) {
console.log(`SET trap ${prop}`);
return Reflect.set(target, prop, value);
}
});
customElements.define('my-state', oProxy);
const oStateEl = document.querySelector('my-state');
console.log(oStateEl.someValue);
console.log(oStateEl.someValue = 2);
console.log(oStateEl.someValue);
我的浏览器似乎没有上述代码的问题,并且在设置元素时我可以看到一些陷阱输出
GET trap prototype
GET trap disabledFeatures
GET trap formAssociated
GET trap prototype
但是当我手动设置 get/set 值时,不会触发陷阱。
这甚至可能吗?
我最终做的是将所有成员变量值移动到一个私有对象,并在自定义元素安装在 DOM 上时为每个变量动态定义一个 getter/setter,就像这样...... .
//
class State extends HTMLElement {
protected _data: object = {}
public connectedCallback() {
// Loop over member vars
Object.getOwnPropertyNames(this).forEach(sPropertyKey => {
// Ignore private
if(sPropertyKey.startsWith('_')) {
return;
}
// Copy member var to data object
Reflect.set(this._data, sPropertyKey, Reflect.get(this, sPropertyKey));
// Remove member var
Reflect.deleteProperty(this, sPropertyKey);
// Define getter/setter to access data object
Object.defineProperty(this, sPropertyKey, {
set: function(mValue: any) {
console.log(`setting ${sPropertyKey}`);
Reflect.set(this._data, sPropertyKey, mValue);
},
get: function() {
return this._data[sPropertyKey];
}
});
});
}
}
//
class SubState extends State {
public foobar = 'foobar_val';
public flipflop = 'flipflop_val';
public SubStateMethod() { }
}
//
window.customElements.define('sub-state', SubState);
//
const oState = document.querySelector('sub-state') as SubState;
oState.foobar = 'foobar_new_val';
这样我仍然可以像往常一样在对象上 get/set 值,打字稿很高兴成员变量存在,并且我可以在访问成员时触发自定义事件 - 同时允许自定义元素存在于其中DOM 处的标记就绪
我正在使用 customElements.define 注册一些自定义元素,并希望在成员访问器上自动设置陷阱,以便我可以在它们发生变化时发出事件
class State extends HTMLElement {
public someValue = 1;
public constructor() {
super();
console.log('State constructor');
}
}
const oProxy = new Proxy(State, {
get(target, prop: string) {
console.log(`GET trap ${prop}`);
return Reflect.get(target, prop);
},
set(target, prop: string, value: any) {
console.log(`SET trap ${prop}`);
return Reflect.set(target, prop, value);
}
});
customElements.define('my-state', oProxy);
const oStateEl = document.querySelector('my-state');
console.log(oStateEl.someValue);
console.log(oStateEl.someValue = 2);
console.log(oStateEl.someValue);
我的浏览器似乎没有上述代码的问题,并且在设置元素时我可以看到一些陷阱输出
GET trap prototype
GET trap disabledFeatures
GET trap formAssociated
GET trap prototype
但是当我手动设置 get/set 值时,不会触发陷阱。 这甚至可能吗?
我最终做的是将所有成员变量值移动到一个私有对象,并在自定义元素安装在 DOM 上时为每个变量动态定义一个 getter/setter,就像这样...... .
//
class State extends HTMLElement {
protected _data: object = {}
public connectedCallback() {
// Loop over member vars
Object.getOwnPropertyNames(this).forEach(sPropertyKey => {
// Ignore private
if(sPropertyKey.startsWith('_')) {
return;
}
// Copy member var to data object
Reflect.set(this._data, sPropertyKey, Reflect.get(this, sPropertyKey));
// Remove member var
Reflect.deleteProperty(this, sPropertyKey);
// Define getter/setter to access data object
Object.defineProperty(this, sPropertyKey, {
set: function(mValue: any) {
console.log(`setting ${sPropertyKey}`);
Reflect.set(this._data, sPropertyKey, mValue);
},
get: function() {
return this._data[sPropertyKey];
}
});
});
}
}
//
class SubState extends State {
public foobar = 'foobar_val';
public flipflop = 'flipflop_val';
public SubStateMethod() { }
}
//
window.customElements.define('sub-state', SubState);
//
const oState = document.querySelector('sub-state') as SubState;
oState.foobar = 'foobar_new_val';
这样我仍然可以像往常一样在对象上 get/set 值,打字稿很高兴成员变量存在,并且我可以在访问成员时触发自定义事件 - 同时允许自定义元素存在于其中DOM 处的标记就绪