如何制作圆形进度条可插入小部件 | Mendix

跳到主要内容

如何制作圆形进度条可插入小部件

如何制作圆形进度条可插入小部件

我很少有机会在日常生活中创建可插入的小部件,因此为了保持技能的新鲜感,我喜欢挑战自己,尝试重新创建一个我经常使用的小部件。我已经有一段时间没这样做了,所以本周我决定测试我的技能,并尝试重新创建本机移动资源模块中的圆形进度条小部件。所以系好安全带,让我们踏上 React 世界的探索之旅, Mendix.


开始之前

请花一点时间确保在我们开始之前已设置好一切。您将需要:

  • Mendix Studio Pro(在此示例中我使用了(9.1.1)。
  • 您的机器上安装并配置了 Node js。
  • 您选择的 IDE,我为此使用了 VS Code。
  • 建议您完成此操作 可插入小部件教程 从文档中或者你已经完成了这个 学院课程.
  • 这个 让其原生 9 安装在测试设备上的应用

选择要使用的 GitHub 库

对于开发人员来说,知道从哪里开始这样的项目有时会令人望而生畏,这就是为什么我发现在进行一些研究之后,知道该做什么要容易得多。所以我去了 github,看看那里已经有什么。我偶然发现了这个 repo epicode 学院 并决定以此为基础创建我的组件。这个仓库里还有其他一些项目,所以如果你正在寻找确切的链接,可以访问 点击这里.

分析代码

在开始编写代码之前,务必实际查看提供的代码并确保了解正在发生的事情。查看示例,我已经可以看到它使用了函数组件,并且我知道这需要进行一些更改才能在可插入小部件中实现,因为主要组件通常是类组件。

组件有两种类型:类组件和函数组件。函数组件只是一个普通的 JavaScript 函数,它接受 props 作为参数并返回一个 React 元素。类组件需要从 React 扩展。

创建小部件支架

阅读够了,让我们开始编码吧!首先,打开终端并导航到您的项目目录。一种快速的方法是单击 Studio Pro 顶部菜单中“App”下的“在资源管理器中显示应用程序目录”。这将打开一个文件资源管理器,其中包含您的应用程序的文件。复制导航栏中的文件路径,然后返回到您打开的终端。输入“cd”并粘贴您的文件路径,如下所示:

cd yourFilePath

接下来我们必须创建一个文件夹来存储自定义小部件。在您的终端中输入:

mkdir CustomWidgets

然后使用 cd 进入刚刚创建的文件夹:

cd CustomWidgets

现在,您可以使用小部件构建器为您创建小部件支架。再次在终端中,使用此命令调用 Mendix 小部件生成器:

@mendix/widget CircularProgressBar

然后,小部件生成器将通过询问一些问题来指导您完成小部件的创建,以下是我所使用的:

  • 小部件名称: {您的小部件名称}
  • 小部件描述: {您的小工具描述}
  • 机构名称: {您的组织名称}
  • 版权: {您的版权日期}
  • 许可证: {您的许可证}
  • 初始版本:{您的初始版本号}
  • 作者: {您的作者姓名}
  • Mendix 项目路径: ../../
  • 编程语言: JavaScript ES6
  • 小部件类型: 原生移动
  • 小部件模板: 空的小部件(推荐给更有经验的开发人员)
  • 单元测试: 没有
  • 端到端测试: 没有

设置小部件 XML

我们需要做的第一件事是修改小部件 XML,以便我们可以以属性的形式从上下文实体接收数据。为此,我们需要创建一个可以接受整数值的属性,定义此属性的键值也很重要。您可以在下面看到我的小部件 XML。

<?xml version="1.0" encoding="utf-8"?>
<widget id="mendix.circularprogressbar.CircularProgressBar" needsEntityContext="true" offlineCapable="true" pluginWidget="true"
supportedPlatform="Native" xmlns="http://www.mendix.com/widget/1.0/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../node_modules/mendix/custom_widget.xsd">
<name>Circular Progress Bar</name>
<description>Animated Circle Progress widget</description>
<icon>
iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABp1BMVEUAAABV//9mzP9LtP9Ms/9Jtv9NsvdJsfpLtPpJsfdJsfhJsvhJsvdKsvdJsPhKsPhJsfdJsPhJsfdIsfhJsfdIsPdJsfhJsfhJsPhJsPhIsfhIsPdJsPdKsPdKsfdNsvdOsvdPs/dQs/dRtPdStPdTtPdUtfdWtvdXtvdauPdcuPdeufdeufhguvhiu/hju/hkvPhmvfhnvfhpvvhrv/huwPhvwfhxwfhywvhzwvh4xfl5xfl6xfl8xvl9xvl9x/mByPmCyfmFyvmGyvmJzPmKzPmLzfmNzvqPzvqQz/qT0PqU0PqU0fqX0vqY0vqa0/qe1fqg1vqj1/uk1/un2fup2vut2/uv3Puw3Puw3fuz3vu13/u23/u34Pu44Pu64fu64fy84vy94vy+4/y/4/zD5fzE5fzG5vzH5vzI5/zK6PzL6PzR6/zT7P3U7P3V7f3W7f3Y7v3Z7v3c8P3e8f3f8f3g8f3i8v3l8/3l9P3n9P3r9v7t9/7u9/7v+P7w+P7x+f7y+f70+v71+v74/P75/P76/f77/f78/f78/v79/v7+/v7////6dMsRAAAAG3RSTlMAAwURGxwhMTNic3SEh4iVp7XBzejt7vH5/f6PsMNWAAABsklEQVR4AWIYfGAUjIJRMAqYuYREJKWJAqLCPGwY+jnFpEkBEryMqPr5pEkFgkwo9kuTDviR/S9GhgFSHAgDuKXJAQIIA4TIMkAcEY4i0mQBVrgBkuQZwA43QJo8wIFhQEhEOIBQOutHJozDOP5Crp4e1RhkJ0tKGJFd6oNEdtmJyEIzpaZl5nrRZgaHM/2Pf5/vwXXfyagXgG93bwSAlEolowLMm9w83gibhXH2gKKVdD67gTnWjwCk+VVjMQS4suSnnjMLRVFc9sAHvAX2A9fySaXNBMbEZVUWscaHIMRuqwBgD8hDEbnsRmfjUKJkAQZGCTlO/xWBwIADQLIZBlY441MvfoF1xlFS/4fy+bzXKh4dgNJE7L3eh3tmtuWa+AMcMIY3dgUvZQpGEYmMw2kD7HC+R29UqyoXLaBd0QZxzgXgikLLDSqJTKU5HOcS0MsbA9jPqtwCRvXm2eorBbNIJBw3KJ9O4Yl+AAXdnyaLt7PWN3jRWLvzmAVp94zO5+n41/onfo/UpExxZqI0O7NQr0DhIq9Io7hQpbRYp7hiobRqo6ByFcNWuY6CUTAKRgEAo8X0lBD3V30AAAAASUVORK5CYII=
</icon>
<properties>
<propertyGroup caption="General">
<property key="progress" type="attribute" required="true">
<caption>Progress Indicator</caption>
<description>The attribute that contains the circularprogressbar value, should be an integer between 0 and 100</description>
<attributeTypes>
<attributeType name="Integer"/>
</attributeTypes>
</property>
</propertyGroup>
</properties>
</widget>

主要成分

现在我们已经定义了数据输入,我们可以开始处理主组件了。在这种情况下,主组件只是用于渲染子组件以及使用其 props 传递数据。

“Props” 是 React 中一个特殊的关键字,代表属性,用于将数据从一个组件传递到另一个组件。但这里重要的是,数据 props 仅以单向(单向)流传递。

这里需要注意的是,如前所述,Main 组件在脚手架中作为类组件创建。这意味着我们需要稍微修改一下 Github 代码。

这是我的主要组件CircularProgressBar 的代码。

import { React,Component ,createElement} from "react";
import CircularProgress from "./components/CircleComponent";
export class CircularProgressBar extends Component {
constructor(props){
super(props);
this.handleChange =this.handleChange.bind(this);
const {progress} = this.props;
console.log('constuctor triggered');
}
render() {
const {progress} = this.props;
console.log('render triggered');
return (
<CircularProgress
progress={progress.value}
size={200}
/>
)
}
}

子组件

子组件是我们大部分逻辑发生的地方。在这里,我们再次使用 props 接受来自父组件的数据,一些逻辑和来自“styled-components/native”的样式库来设置进度条组成部分样式。最后,我们以应呈现组件的 return 语句结束。查看下面的子组件“CircleComponent”代码。

import React, { useRef, useEffect, createElement } from "react";
import styled from 'styled-components/native';
import {Animated} from 'react-native';
const EmptyColour = '#a0a0a1';
const ProgressColour = '#0085ff';
const CircleBase = styled(Animated.View)`
width: ${props => props.size}px;
height: ${props => props.size}px;
border-radius: ${props => props.size / 2}px;
border-width: ${props => props.size / 10}px;
`;
const EmptyCircle = styled(CircleBase)`
border-color: ${EmptyColour};
justify-content:center;
align-items: center;
transform: rotate(-45deg);
`;
const Indicator = styled(CircleBase)`
position: absolute;
border-left-color:${ProgressColour};
border-top-color:${ProgressColour};
border-bottom-color:transparent;
border-right-color:transparent;
`;
const CoverIndicator = styled(CircleBase)`
position: absolute;
border-left-color:${EmptyColour};
border-top-color:${EmptyColour};
border-bottom-color:transparent;
border-right-color:transparent;
`;
export default function CircularProgress(props) { //added input props
const {progress, size} = this.props //destructured the props
console.log (styled)
const animatedProgress = useRef(new Animated.Value(0)).current;
const animateProgress = useRef(toValue => {
Animated.spring(animatedProgress, {
toValue,
useNativeDriver: true,
}).start();
}).current;
useEffect(() => {
animateProgress(progress);
}, [animateProgress,progress]);
const firstIndicatorRotate = animatedProgress.interpolate({
inputRange: [0, 50],
outputRange: ['0deg', '180deg'],
extrapolate: 'clamp',
});
const secondIndicatorRotate = animatedProgress.interpolate({
inputRange: [0, 100],
outputRange: ['0deg', '360deg'],
extrapolate: 'clamp',
});
const secondIndictorVisibility = animatedProgress.interpolate({
inputRange: [0, 49, 50, 100],
outputRange: [0, 0, 1, 1],
extrapolate: 'clamp',
});
return (
<EmptyCircle size={size}>
<Indicator
style={{transform: [{rotate: firstIndicatorRotate}]}}
size={size}
/>
<CoverIndicator size={size} />
<Indicator
size={size}
style={{
transform: [{rotate: secondIndicatorRotate}],
opacity: secondIndictorVisibility,
}}
/>
</EmptyCircle>
);
}

安装依赖

现在差不多该测试一下你的小部件了,但在测试之前我们还有一些事情要做。我们必须确保我们使用的所有库都正确导入到我们的小部件文件夹中。再次打开你的终端并输入命令。

npm install --save

等待它下载并安装您的代码可能需要的任何依赖项。

如果出现任何问题或者你需要重做此操作,你也可以执行全新安装,删除所有节点模块,然后使用此命令重新安装它们 (但只有在 100% 需要时才这样做!)

npm ci --save

创建小部件 .mpk 文件

要捆绑您的小部件并创建可在您的 Mendix 项目,在终端中运行以下命令:

npm run build

此操作将构建您的小部件代码,然后将小部件复制到您的小部件文件夹中。最后一步是同步 Studio Pro 中的应用程序目录,方法是按 F4 或转到 Studio Pro 顶部菜单中的“应用程序”→“同步应用程序目录”。

现在,您可以在 Studio Pro 中开发时访问您的小部件。小部件需要放置在数据视图中以获取上下文,并且需要将整数属性与其连接,但是一旦您设置好它,您就可以使用 Make it Native 9 应用程序运行和测试您的新小部件。

阅读有关制作可插入小部件的更多信息


选择你的语言