Web 组件:setter 未被调用
Web Components: setter not being called
假设我有一个 Web 组件:
customElements.define("custom-list", class CustomList extends HTMLElement {
get filter() {
console.log("get filter");
return this.getAttribute("filter");
}
set filter(value) {
console.log("set filter");
this.setAttribute("filter", value);
}
});
我想使用 setter 方法进行一些初始属性验证,但从未调用 setter。我尝试通过 HTML:
设置属性
<custom-list filter="some value"></custom-list>
只有当我使用 JavaScript 以编程方式设置 属性 时,才会调用 setter:
var list = document.querySelector("custom-list");
list.filter = "some value";
list.setAttribute("filter", "some value"); // DOESN'T WORK EITHER
所以,似乎通过HTML设置属性或使用setAttribute
不会触发setter,我能部分理解。我的问题是:
- 仅当我想以编程方式设置属性时才需要setter吗?
- 如何对属性进行初始验证?在
connectedCallback
?假设我只想接受某个字符串,我该如何检测?
- 既然 属性
filter
无论如何都会被填充,如果我不使用 JavaScript 来设置我的属性,我还需要 setter 吗?
- 只有当我想以编程方式设置属性时才需要 setter 吗?
是的,至少如果您 want/need 到 运行 一些 tests/filtering 要设置的值。
- 如何对属性进行初始验证?在 connectedCallback 中?假设我只想接受某个字符串,我该如何检测?
是的,connectedCallback 甚至在构造函数中。
- 既然 属性 过滤器无论如何都会被填充,如果我不使用 JavaScript 来设置我的属性,我还需要 setter 吗?
不,你没有
也就是说,如果您需要对自定义属性进行明确控制,我建议创建一个内部状态,在创建自定义元素时填充一次,然后在调用 attributeChangedCallback 时填充一次。那会给你一些优势:
- 您可以控制为您的自定义属性赋值的值。
- 你得到了一个内部状态,如果你需要
,你可以用它来 re-render 你的组件
这是一个例子:
customElements.define("custom-list", class CustomList extends HTMLElement {
static get observedAttributes() { return ['filter']; }
constructor() {
super();
this.state = {
filter: null
};
this.setFilter(this.getAttribute("filter"));
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === "filter") {
this.setFilter(newValue);
}
}
getFilter() {
console.log("get filter");
return this.state.filter;
}
setFilter(value) {
// You can add some logic here to control the value
console.log("set filter");
this.state.filter=value;
}
});
然后你可以调用下面的代码来改变你的内部状态:
list.setAttribute("filter", "some value");
很想从社区获得一些对此的反馈。无论如何,希望这会有所帮助:)
getters 和 setter 允许您的代码接收字符串以外的值。属性始终是字符串,只能由 JavaScript.
调用
您可以通过解析值来模拟属性中的 non-string。但它们总是作为字符串传入。
如果您想在更改属性时使用代码 运行,则需要添加 attributeChangedCallback
函数并在 observedAttributes
static getter。可以通过调用 setAttribute
和 removeAttribute
在 JavaScript 中设置属性。当浏览器由于页面加载或设置 innerHTML
解析您的 HTML 时,也会设置它们。但即便如此,浏览器最终还是会在后台调用 setAttribute
。
customElements.define("custom-list", class CustomList extends HTMLElement {
static get observedAttributes() { return ['filter']; }
constructor() {
super();
this._filter = null;
}
attributeChangedCallback(attr, oldVal, newVal) {
if (oldVal != newVal) {
// Only set this value if it is different
this.filter = newVal;
}
}
get filter() {
console.log("get filter");
return this._filter;
}
set filter(value) {
if (value !== this._filter) {
console.log(`set filter ${value}`);
this._filter=value;
this.textContent = value;
// If you want the filter property to always show
// in the attributes then do this:
if (value !== null) {
this.setAttribute('filter', value);
} else {
this.removeAttribute('filter');
}
}
}
});
const el = document.querySelector('custom-list');
setTimeout(() => {
el.filter = 'happy';
}, 2000);
<custom-list filter="10"></custom-list>
始终 检查您的 oldVal
和 newVal
在函数 attributeChangedCallback
.
中是否不同
还建议您检查设置器中的不同值。
Setter 还允许您获取特定的数据类型。例如,您可以检查 value
的值是否为数字,如果不是,则抛出 TypeError
.
设置器还允许您确保值有效。也许它必须是正数或三个可能的字符串之一。如果不是,你可以抛出一个 RangeError
.
但是你必须记住属性总是字符串。属性可以是任何东西。
假设我有一个 Web 组件:
customElements.define("custom-list", class CustomList extends HTMLElement {
get filter() {
console.log("get filter");
return this.getAttribute("filter");
}
set filter(value) {
console.log("set filter");
this.setAttribute("filter", value);
}
});
我想使用 setter 方法进行一些初始属性验证,但从未调用 setter。我尝试通过 HTML:
设置属性<custom-list filter="some value"></custom-list>
只有当我使用 JavaScript 以编程方式设置 属性 时,才会调用 setter:
var list = document.querySelector("custom-list");
list.filter = "some value";
list.setAttribute("filter", "some value"); // DOESN'T WORK EITHER
所以,似乎通过HTML设置属性或使用setAttribute
不会触发setter,我能部分理解。我的问题是:
- 仅当我想以编程方式设置属性时才需要setter吗?
- 如何对属性进行初始验证?在
connectedCallback
?假设我只想接受某个字符串,我该如何检测? - 既然 属性
filter
无论如何都会被填充,如果我不使用 JavaScript 来设置我的属性,我还需要 setter 吗?
- 只有当我想以编程方式设置属性时才需要 setter 吗?
是的,至少如果您 want/need 到 运行 一些 tests/filtering 要设置的值。
- 如何对属性进行初始验证?在 connectedCallback 中?假设我只想接受某个字符串,我该如何检测?
是的,connectedCallback 甚至在构造函数中。
- 既然 属性 过滤器无论如何都会被填充,如果我不使用 JavaScript 来设置我的属性,我还需要 setter 吗?
不,你没有
也就是说,如果您需要对自定义属性进行明确控制,我建议创建一个内部状态,在创建自定义元素时填充一次,然后在调用 attributeChangedCallback 时填充一次。那会给你一些优势:
- 您可以控制为您的自定义属性赋值的值。
- 你得到了一个内部状态,如果你需要 ,你可以用它来 re-render 你的组件
这是一个例子:
customElements.define("custom-list", class CustomList extends HTMLElement {
static get observedAttributes() { return ['filter']; }
constructor() {
super();
this.state = {
filter: null
};
this.setFilter(this.getAttribute("filter"));
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === "filter") {
this.setFilter(newValue);
}
}
getFilter() {
console.log("get filter");
return this.state.filter;
}
setFilter(value) {
// You can add some logic here to control the value
console.log("set filter");
this.state.filter=value;
}
});
然后你可以调用下面的代码来改变你的内部状态:
list.setAttribute("filter", "some value");
很想从社区获得一些对此的反馈。无论如何,希望这会有所帮助:)
getters 和 setter 允许您的代码接收字符串以外的值。属性始终是字符串,只能由 JavaScript.
调用您可以通过解析值来模拟属性中的 non-string。但它们总是作为字符串传入。
如果您想在更改属性时使用代码 运行,则需要添加 attributeChangedCallback
函数并在 observedAttributes
static getter。可以通过调用 setAttribute
和 removeAttribute
在 JavaScript 中设置属性。当浏览器由于页面加载或设置 innerHTML
解析您的 HTML 时,也会设置它们。但即便如此,浏览器最终还是会在后台调用 setAttribute
。
customElements.define("custom-list", class CustomList extends HTMLElement {
static get observedAttributes() { return ['filter']; }
constructor() {
super();
this._filter = null;
}
attributeChangedCallback(attr, oldVal, newVal) {
if (oldVal != newVal) {
// Only set this value if it is different
this.filter = newVal;
}
}
get filter() {
console.log("get filter");
return this._filter;
}
set filter(value) {
if (value !== this._filter) {
console.log(`set filter ${value}`);
this._filter=value;
this.textContent = value;
// If you want the filter property to always show
// in the attributes then do this:
if (value !== null) {
this.setAttribute('filter', value);
} else {
this.removeAttribute('filter');
}
}
}
});
const el = document.querySelector('custom-list');
setTimeout(() => {
el.filter = 'happy';
}, 2000);
<custom-list filter="10"></custom-list>
始终 检查您的 oldVal
和 newVal
在函数 attributeChangedCallback
.
还建议您检查设置器中的不同值。
Setter 还允许您获取特定的数据类型。例如,您可以检查 value
的值是否为数字,如果不是,则抛出 TypeError
.
设置器还允许您确保值有效。也许它必须是正数或三个可能的字符串之一。如果不是,你可以抛出一个 RangeError
.
但是你必须记住属性总是字符串。属性可以是任何东西。