如何获取Web Component 中customElement 创建的对象?
How to get the object created by customElement in a Web Component?
我正在构建一个要在框架中使用的 Web 组件,它嵌入了一个网格库。
我已经设法通过将网格包装在 HTMLElement 中来显示网格 Class
export default class DataGrid extends HTMLElement {
constructor() {
super();
let tmpl = document.createElement('template');
tmpl.innerHTML = `
<div id="lib-datagrid"></div>
`;
this._shadowRoot = this.attachShadow({mode: "open"});
this._shadowRoot.appendChild(tmpl.content.cloneNode(true));
this._rowData = [];
...
}
和
// Load the grid
customElements.define('my-grid', DataGrid);
我需要能够通过 DataGrid 实例将数据传递到 Grid 中。但是,createElements.define()
似乎采用 Class 而不是对象实例,因此我没有创建实例 (new DataGrid()
) 并将其传入的选项。
我的理论是我应该能够通过 dom 树检索创建的元素,但我的 Web 组件位于阴影 Dom 中,而我的 Web 组件本身不是 Dom 元素(我认为)即没有“this.getRootNode()”等,但可以访问 document
和 window
.
我是不是在 createElement
过程中遗漏了什么,或者有没有办法找到当前影子的根节点 dom?
** 编辑 - 添加顶级 WebComponent 视图
export default (state) => {
const { items, alert, loading } = state;
return (
<div>
<div className="card-top">
<my-grid></my-grid>
</div>
</div>
);
};
** 编辑 2
我发现在线编码 class extends HTMLElement
(而不是在单独的 js 文件中)确实允许我更新对象 connectedCallback()
函数的引用。
let myobject = null;
customElements.define('my-grid2', class extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({mode: 'open'});
shadow.innerHTML = `<p>
Hello
</p>`;
myobject = this;
}
});
待定其他建议 - 我会处理这个问题,post 如果可行,我会给予答复。
在 customElements.define('my-grid', DataGrid)
之后,您必须使用以下方法实际创建一个元素:
const elm = document.createElement('my-grid');
const orElm = new DataGrid();
// Use `elm` or `orElm` to pass the data.
如果您的 Web 组件是通过其他方式添加到 DOM 树中的,那么您必须使用 querySelector 或类似方法找到它:
const elm = document.querySelector('my-grid');
但如果它嵌套在其他一些 shadow-root
中,那么 querySelector
将无法执行此操作。为此,您必须精确地找到父元素,获取其阴影根,然后在该阴影根上 运行 querySelector
,例如:
const shadowroot = parentElement.shadowRoot;
shadowroot.querySelector('my-grid');
附带说明一下,如果您需要从 Web 组件外部查询或发送数据,那么这可能是代码味道,因为您违反了 封装法则 。还有其他更好的方法可以将数据传递给子组件。否则,你不需要 shadow DOM API。只使用没有阴影的自定义元素 DOM.
我找到了一种方法。
通过在线定义 HTMLElement
class 并在 connectedCallback()
函数中处理网格包装器对象,我可以访问 element
的引用创建和 DataGrid 包装器对象。
DataGrid 包装器只需要 shadowRoot
作为构造函数参数创建。
let myElement = null;
let myDataGrid = null;
// Load the grid
customElements.define('my-grid', class extends HTMLElement {
connectedCallback() {
let tmpl = document.createElement('template');
tmpl.innerHTML = `
<div id="lib-datagrid"></div>
`;
const shadow = this.attachShadow({mode: 'open'});
shadow.appendChild(tmpl.content.cloneNode(true));
myDataGrid = new DataGrid(shadow);
myElement = this;
}
});
现在我可以稍后调用 DataGrid
对象上的函数来更新数据。
只是为了节省您的输入时间
你可以这么写:
connectedCallback() {
let tmpl = document.createElement('template');
tmpl.innerHTML = `
<div id="lib-datagrid"></div>
`;
const shadow = this.attachShadow({mode: 'open'});
shadow.appendChild(tmpl.content.cloneNode(true));
myDataGrid = new DataGrid(shadow);
myElement = this;
}
如:
connectedCallback() {
this.attachShadow({mode: 'open'}).innerHTML = `<div></div>`;
myDataGrid = new DataGrid(this.shadowRoot);
myElement = this;
}
我正在构建一个要在框架中使用的 Web 组件,它嵌入了一个网格库。
我已经设法通过将网格包装在 HTMLElement 中来显示网格 Class
export default class DataGrid extends HTMLElement {
constructor() {
super();
let tmpl = document.createElement('template');
tmpl.innerHTML = `
<div id="lib-datagrid"></div>
`;
this._shadowRoot = this.attachShadow({mode: "open"});
this._shadowRoot.appendChild(tmpl.content.cloneNode(true));
this._rowData = [];
...
}
和
// Load the grid
customElements.define('my-grid', DataGrid);
我需要能够通过 DataGrid 实例将数据传递到 Grid 中。但是,createElements.define()
似乎采用 Class 而不是对象实例,因此我没有创建实例 (new DataGrid()
) 并将其传入的选项。
我的理论是我应该能够通过 dom 树检索创建的元素,但我的 Web 组件位于阴影 Dom 中,而我的 Web 组件本身不是 Dom 元素(我认为)即没有“this.getRootNode()”等,但可以访问 document
和 window
.
我是不是在 createElement
过程中遗漏了什么,或者有没有办法找到当前影子的根节点 dom?
** 编辑 - 添加顶级 WebComponent 视图
export default (state) => {
const { items, alert, loading } = state;
return (
<div>
<div className="card-top">
<my-grid></my-grid>
</div>
</div>
);
};
** 编辑 2
我发现在线编码 class extends HTMLElement
(而不是在单独的 js 文件中)确实允许我更新对象 connectedCallback()
函数的引用。
let myobject = null;
customElements.define('my-grid2', class extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({mode: 'open'});
shadow.innerHTML = `<p>
Hello
</p>`;
myobject = this;
}
});
待定其他建议 - 我会处理这个问题,post 如果可行,我会给予答复。
在 customElements.define('my-grid', DataGrid)
之后,您必须使用以下方法实际创建一个元素:
const elm = document.createElement('my-grid');
const orElm = new DataGrid();
// Use `elm` or `orElm` to pass the data.
如果您的 Web 组件是通过其他方式添加到 DOM 树中的,那么您必须使用 querySelector 或类似方法找到它:
const elm = document.querySelector('my-grid');
但如果它嵌套在其他一些 shadow-root
中,那么 querySelector
将无法执行此操作。为此,您必须精确地找到父元素,获取其阴影根,然后在该阴影根上 运行 querySelector
,例如:
const shadowroot = parentElement.shadowRoot;
shadowroot.querySelector('my-grid');
附带说明一下,如果您需要从 Web 组件外部查询或发送数据,那么这可能是代码味道,因为您违反了 封装法则 。还有其他更好的方法可以将数据传递给子组件。否则,你不需要 shadow DOM API。只使用没有阴影的自定义元素 DOM.
我找到了一种方法。
通过在线定义 HTMLElement
class 并在 connectedCallback()
函数中处理网格包装器对象,我可以访问 element
的引用创建和 DataGrid 包装器对象。
DataGrid 包装器只需要 shadowRoot
作为构造函数参数创建。
let myElement = null;
let myDataGrid = null;
// Load the grid
customElements.define('my-grid', class extends HTMLElement {
connectedCallback() {
let tmpl = document.createElement('template');
tmpl.innerHTML = `
<div id="lib-datagrid"></div>
`;
const shadow = this.attachShadow({mode: 'open'});
shadow.appendChild(tmpl.content.cloneNode(true));
myDataGrid = new DataGrid(shadow);
myElement = this;
}
});
现在我可以稍后调用 DataGrid
对象上的函数来更新数据。
只是为了节省您的输入时间
你可以这么写:
connectedCallback() {
let tmpl = document.createElement('template');
tmpl.innerHTML = `
<div id="lib-datagrid"></div>
`;
const shadow = this.attachShadow({mode: 'open'});
shadow.appendChild(tmpl.content.cloneNode(true));
myDataGrid = new DataGrid(shadow);
myElement = this;
}
如:
connectedCallback() {
this.attachShadow({mode: 'open'}).innerHTML = `<div></div>`;
myDataGrid = new DataGrid(this.shadowRoot);
myElement = this;
}