2025年已经过去一半了,我还没做出一个部件。再加上 Mendix Linux 11 正式发布,我突然感觉有些生疏了。跟上自己喜欢的技术总是好的,所以我决定自己做个东西来测试一下,保持技能的敏锐。
挑战
为 Web 应用构建一个简单的视频播放器小部件,无需 GitHub 或其他代码共享平台的仓库。此外,我将使用 TypeScript 进行开发。
1。 制备
我的第一步是安装并更新所有需要的工具。如果你也跟着操作,请务必下载并安装:
最后,我完成了 可插入小部件教程 in Mendix 文档,复习基础知识。
2.入门
为了开始开发,我在 Studio Pro 中创建了一个新应用程序。
- 使用空白 Web 应用程序模板在 Studio Pro 中创建一个新应用程序。
- 导航到项目目录。
- 创建一个名为 MyWidget 的新文件夹
- 打开终端并导航到文件夹
3. 搭建小部件
使用 Yeoman Widget Generator 生成 Widget 脚手架非常简单。首先,在我已经打开的终端中,我使用以下命令启动了生成器:
npx @mendix/generator-widget MyVideoPlayer
然后,生成器通过几个简单的问题引导我完成剩余的设置:
Widget name: MyVideoPlayer
Widget Description: My widget description
Organization Name: Mendix
Copyright: {Your copyright date}
License: {Your license}
Initial Version: {Your initial version number}
Author: {Your author name}
Mendix App path: ../../
Programming language: TypeScript
Which type of components do you want to use? Function Components
Widget type: For web and hybrid mobile apps
Widget template: Empty widget (recommended for more experienced developers)
Unit tests: No
End-to-end tests: No
回答完所有问题后,Widget Generator 在我的应用目录中创建了所需的文件。然后我打开了 我的视频播放器 在 Visual Studio Code 中打开文件以开始对小部件进行编码。
4. 定义小部件属性
现在小部件框架已经存在,我们可以开始添加内容了。我使用 xml 更新了小部件属性,如下所示: 我的视频播放器.xml 文件中。
<?xml version="1.0" encoding="utf-8"?>
<widget id="mendix.myvideoplayer.MyVideoPlayer" pluginWidget="true" needsEntityContext="true" offlineCapable="true" supportedPlatform="Web"
xmlns="https://www.mendix.com/widget/1.0/"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.mendix.com/widget/1.0/ ../node_modules/mendix/custom_widget.xsd">
<name>My Video Player</name>
<description>My widget description</description>
<icon/>
<properties>
<propertyGroup caption="General">
<property key="videoUrl" type="attribute" required="true">
<caption>Video URL</caption>
<description>Direct URL to the video file (e.g. CDN/API)</description>
<attributeTypes>
<attributeType name="String"/>
</attributeTypes>
</property>
<property key="controls" type="boolean" defaultValue="true">
<caption>Show controls</caption>
<description>Toggles controls on or off</description>
</property>
<property key="autoPlay" type="boolean" defaultValue="true">
<caption>Autoplay</caption>
<description>Autoplay on video load</description>
</property>
<property key="muted" type="boolean" defaultValue="true">
<caption>Muted</caption>
<description>Include sound with your video</description>
</property>
<property key="loop" type="boolean" defaultValue="true">
<caption>Loop</caption>
<description>Enable back to back playback</description>
</property>
<property key="width" type="integer" defaultValue="640">
<caption>Width (px)</caption>
<description>Width of the video player in pixels</description>
</property>
<property key="height" type="integer" defaultValue="360">
<caption>Height (px)</caption>
<description>Height of the video player in pixels</description>
</property>
</propertyGroup>
</properties>
</widget>
- 视频 URL(字符串)
- 显示控件(布尔值)
- 自动播放(布尔值)
- 静音(布尔值)
- 循环(布尔)
- 宽度(整数)
- 高度(整数)
这些只是在 Studio Pro 中配置小部件属性的一些基本选项,URL 通过字符串属性 VideoURL 传递,必须在小部件外部设置并通过上下文实体传递。
5. 实现小部件
处理好属性后,我开始创建小部件本身。我打开 MyVideoPlayer.tsx 在 Visual Studio Code 中。作为我设定的挑战的一部分,我无法使用任何视频库来制作这个小部件。我决定只使用 播放视频。以下代码是我创建视频播放器、传入属性并在页面上显示视频的方法。
import {createElement, useRef} from "react";
import "./ui/MyVideoPlayer.css";
// The generator creates this file for you after editing the XML:
import type { MyVideoPlayerContainerProps } from "../typings/MyVideoPlayerProps";
export default function MyVideoPlayer(props: MyVideoPlayerContainerProps) {
const videoUrl = props.videoUrl?.value ?? "";//assing video url to entity attribute in Studio Pro
const {
controls,
autoPlay,
muted,
loop,
width,
height,
class: className,
style,
tabIndex
} = props;
const videoRef = useRef(null);
if (!videoUrl || videoUrl.length === 0) {//URL String validation
return (
//Video Player error message
No video URL provided
);
}
return (//return video player
); }
6. 值得拥有
完成小部件之前的最后一步是更新 MyVideoPlayer.editorPreview.tsx 文件。这是 Studio Pro 在设计时用来在编辑器窗口中显示的内容(小部件在 Studio Pro 中的外观,而不是在浏览器中的外观)。
这只是返回一个附加了一些简单样式的 div,以便小部件看起来具有漂亮的设计视图。
import { createElement } from "react";
export function preview() {
return (
<div
style={{
width: 320,
height: 180,
border: "1px dashed #bbb",
borderRadius: 12,
display: "grid",
placeItems: "center",
fontSize: 12,
color: "#666"
}}
>
Video Player (bind Video URL)
</div>
);
}
export function getPreviewCss() {
return "";
}
7. 将小部件添加到 Studio Pro
现在工作已经完成,我使用终端中的构建命令编译了小部件。
npm run build //(You can also use npm start to have the widget autocompile after every change)
此命令将代码编译成一个包并将其复制到应用程序的小部件文件夹中。
8. 在 Studio Pro 中
成功构建小部件后,将应用程序与项目目录同步并更新所有小部件非常重要,否则它可能不会显示在工具箱中。
- 我在域模型中创建了一个名为 视频。实体是 文件文档 并具有三个属性: 标题(字符串)、视频ID(自动编号)和 视频URL(字符串).
- 该小部件需要一个 URL 来播放视频。为了实现这一点,我决定将视频以 REST API 的形式公开,并使用 视频ID(自动编号) 作为关键 获取键值 端点。REST API 的 URL 可以作为视频播放器的 URL。

我选择从域模型生成 REST API,通过右键单击视频实体并选择将其公开为 REST API。我让 Studio Pro 创建 API,并使用 自动编号 字段作为服务的键(我创建了 得到所有 和 通过密钥获取 API 的端点,但只有 通过密钥获取 是需要的)。我修改了 通过密钥获取 端点,通过更新处理响应的微流。

为了使服务正常工作,必须将正确的 Content Type 标头附加到响应中。我添加了包含以下值的 HTTPHeader:
- 键:内容类型
- 值:video/mp4
我还将关联设置为 HTTP 响应实体。

9. 配置小部件
该小部件需要来自上下文实体的属性,因此在将其添加到页面时我将其放在数据视图中。

然后我打开它的属性来配置它。
- 视频 URL(来自上下文实体的字符串)
- 显示控件(真)
- 自动播放(真)
- 静音(假)
- 循环(假)
- 宽度(640)
- 高度(360)

10.设置URL
最后一步——保存视频文件时自动设置视频的 URL。在视频保存按钮附带的微流中,我添加了一个更改操作,并使用 Community Commons 中的“获取应用程序 URL”Java 操作设置了字符串。
$AppURL+'/rest/myvideoservice/v1/video/'+$Video/VideoID- (例如 https://localhost:8080/rest/myvideoservice/v1/video/2)

11. 测试小部件
完成所有这些后,终于到了测试小部件的时候了。我创建了一个简单的屏幕,用于将视频上传到实体并显示 VideoID 字段,以及显示该视频的 GetByKey API 端点的 URL。

运行应用程序并上传测试视频后,我能够获得视频的完整 URL 并更新小部件的视频 URL 属性。
最后重新运行一下应用程序,我终于看到我的小部件加载正确,视频也播放正常了!终于成功了!
最后的思考
这是一个有趣的挑战,因为我之前在很多项目中都没有用过多媒体。未来,我希望在几个关键领域扩展这个小部件:
-
- 更精致的造型
- 可选功能(2 倍速度、字幕等)
- 为视频添加“海报”(缩略图、图像作为占位符)
我很享受用这个有趣的挑战来考验自己,也希望你们也喜欢阅读。如果你有任何建议、批评或意见,请告诉我,我可能会在以后更新。
常见问题 (FAQ)
-
我是否需要将视频公开为 REST 服务?
这只是其中一种选择。您也可以直接指向提供视频内容的 URL 或 API。
-
我可以设计播放器的风格来匹配我的应用程序吗?
是的,您可以覆盖 CSS 或扩展 React 组件。
-
该小部件是否支持移动应用程序和网络应用程序?
它是为 Web 应用程序设计的,但由于它是使用 React 构建的,因此也可以适用于移动应用程序。