gpt4 book ai didi

javascript - 在 React 组件内运行带有小部件的 PhosphorJS DockerPanel

转载 作者:行者123 更新时间:2023-12-03 14:32:22 24 4
gpt4 key购买 nike

我有一个 React 应用程序,我想在其中一个组件中渲染 Phosphor 桌面 ( http://phosphorjs.github.io )。

网络资源建议采用相反的方式,在 Phosphor Widget 中运行 React 组件,但我需要将 Phosphor 桌面与 React 组件中的小部件包装在一起。不知道该怎么做。

这是我的第一次尝试:

import React, { Component } from 'react';
import './App.css';

import { DockPanel } from 'phosphor-dockpanel';
import { Message } from 'phosphor-messaging';
import { TabPanel } from 'phosphor-tabs';
import { ResizeMessage, Widget } from 'phosphor-widget';


class MyWidget extends Widget {

static createNode() {
console.log('widget:createNode');
var node = document.createElement('div');
var app = document.createElement('div');
app.className = 'todoapp';
node.appendChild(app);
return node;
}

constructor(model) {
super();
this.addClass('TodoWidget');
this._model = model;
console.log('widget:constructor');
}

get model() {
console.log('widget:getModel');
return this._model;
}

onAfterAttach(msg) {
console.log('onAfterAttach');
//this._model.subscribe(() => this.update());
this.update();
}

onUpdateRequest(msg) {
console.log('widget:onUpdateRequest');
var data = { model: this._model };
var host = this.node.firstChild;
//React.render(React.createElement(app.TodoApp, data), host);
}
}


class ReactDockPanel extends Component {
constructor(props) {
super(props);
}

componentWillMount() {
this.panel = new DockPanel();
this.panel.id = this.props.id;

this.widget = new MyWidget();
this.panel.insertLeft(this.widget);
}

componentDidMount() {
this.panel.attach(this.node);
}

render() {
return (
<div ref={el=>this.node=el}>
</div>
);
}
}

class App extends Component {

render() {
return (
<ReactDockPanel id='main'>
</ReactDockPanel>
);
}
}

export default App;

我不知道如何替换 React.render(React.createElement(app.TodoApp, data), host); Phosphor 文档仅供引用,但不用于学习,因此我将使用他们唯一的示例代码。

理想情况下,我希望能够像这样渲染:

<ReactDockPanel id='mydesktop'>
<SomeWidget insert='left' />
<SomeOtherWidget insert='right' />
</ReactDockPanel>

不确定是否可以完成。

最佳答案

我能够使用 React 门户进行类似的工作。就我而言,我尝试渲染 React Component 子级而不是 Widget 子级,但希望它仍然有帮助。我使用的步骤是

1) 在外部 React 组件的初始渲染中,使用 ref 获取对该元素的引用。

2) 在componentDidMount中,创建一个新的DockPanel并将其附加到元素。然后,循环遍历您想要拥有的小部件,a) 将每个小部件添加到 DockPanel,b) 构建一个节点列表,您将在其中渲染 React 组件,并使用以下命令执行 this.setState列表。

3) 在下一个 render 调用中,循环遍历 this.state 中的节点列表并创建门户。

代码看起来像这样:

import {DockPanel, Widget} from "@phosphor/widgets";
import {createPortal} from "react-dom";

interface IWidgetInfo {
component: JSX.Element;
node: HTMLElement;
}

interface IDockState {
widgetInfos: IWidgetInfo[];
}

interface IDockProps {
children: JSX.Element[];
}

class WrapperWidget extends Widget {
constructor(name: string, node: HTMLElement) {
super({node});
this.setFlag(Widget.Flag.DisallowLayout);
this.title.label = name;
}
}

export class Dock extends React.PureComponent<IDockProps, IDockState> {
elem: HTMLElement;
dock: DockPanel;

componentDidMount() {
this.dock = new DockPanel(this.context.store);

let widgetInfos = [];
for (let component of this.props.children) {
let node = document.createElement("div");
let widget = new WrapperWidget("Widget Name", node);
this.dock.addWidget(widget);
widgetInfos.push({node, component});
}
this.setState({...this.state, widgetInfos});

Widget.attach(this.dock, this.elem);
}

render() {
return (
<div ref={(c) => this.elem = c}>
{this.state.widgetsInfos.map(widgetInfo => {
return createPortal(widgetInfo.component, widgetInfo.node);
})}
</div>
);
}
}

关于javascript - 在 React 组件内运行带有小部件的 PhosphorJS DockerPanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45684550/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com