시작하기 전에
진행하기 전에 잠시 시간을 내어 모든 것이 설정되어 있는지 확인하십시오. 필요한 것은 다음과 같습니다.
- Mendix Studio Pro (이 예에서는 (9.1.1)을 사용했습니다.
- 컴퓨터에 Node.js가 설치되고 구성되었습니다.
- 여러분이 선택한 IDE입니다. 저는 여기서 VS Code를 사용했습니다.
- 이 작업을 완료한 것이 좋습니다. 플러그형 위젯에 대한 튜토리얼 문서에서 또는 이것을 완료했습니다 아카데미 과정.
- 따라서 네이티브로 만들어보세요 9 테스트 장치에 앱이 설치됨
사용할 github 라이브러리 선택
이런 프로젝트를 어디서부터 시작해야 할지 아는 것은 개발자에게 때로는 두려울 수 있습니다. 그래서 저는 조사를 좀 한 후에 무엇을 해야 할지 아는 것이 훨씬 쉽다는 것을 알게 되었습니다. 그래서 저는 github에 가서 이미 나와 있는 것을 살펴보았습니다. 저는 이 repo를 발견했습니다. 에피코드-아카데미 이걸 제 컴포넌트의 기반으로 사용하기로 했습니다. 이 저장소에는 다른 프로젝트도 몇 개 있으니 정확한 링크를 찾고 계신다면 여기에서 확인하세요.
코드 분석
코딩을 시작하기 전에 제공된 코드를 실제로 검토하고 무슨 일이 일어나고 있는지 이해하는 것이 중요합니다. 예를 살펴보면 이것이 함수형 구성 요소를 사용한다는 것을 이미 알 수 있으며, 주요 구성 요소가 일반적으로 클래스 구성 요소이기 때문에 플러그형 위젯에 구현하려면 약간의 변경이 필요하다는 것을 알고 있습니다.
컴포넌트는 클래스 컴포넌트와 함수 컴포넌트의 두 가지 유형으로 제공됩니다. 함수형 컴포넌트는 props를 인수로 받아들이고 React 요소를 반환하는 단순한 JavaScript 함수입니다. 클래스 컴포넌트는 React에서 확장해야 합니다.
위젯 스캐폴드 생성
충분히 읽고, 코딩해 봅시다! 시작하려면 터미널을 열고 프로젝트 디렉토리로 이동합니다. 이를 위한 빠른 방법은 Studio Pro의 상단 메뉴에서 "앱" 아래에 있는 "탐색기에 앱 디렉토리 표시"를 클릭하는 것입니다. 그러면 앱의 파일이 있는 파일 탐색기가 열립니다. 탐색 모음에서 파일 경로를 복사한 다음, 열었던 터미널로 돌아갑니다. "cd"를 입력하고 다음과 같이 파일 경로를 붙여넣습니다.
cd yourFilePath
다음으로 사용자 정의 위젯을 저장할 폴더를 만들어야 합니다. 터미널에서 다음을 입력합니다.
mkdir CustomWidgets
그리고 cd를 사용해 방금 만든 폴더로 이동합니다.
cd CustomWidgets
이제 위젯 빌더를 사용하여 위젯 스캐폴드를 만들 수 있습니다. 터미널에서 다시 이 명령을 사용하여 다음을 호출합니다. Mendix 위젯 생성기:
@mendix/widget CircularProgressBar
위젯 생성기는 몇 가지 질문을 통해 위젯을 만드는 과정을 안내합니다. 제가 사용한 질문은 다음과 같습니다.
- 위젯 이름: {귀하의 위젯 이름}
- 위젯 설명: {귀하의 위젯 설명}
- 조직 이름: {귀하의 조직 이름}
- 저작권 : {귀하의 저작권 날짜}
- 특허: {귀하의 라이센스}
- 초기 버전:{초기 버전 번호}
- 저자: {작성자 이름}
- Mendix 프로젝트 경로: ../../
- 프로그래밍 언어: 자바 스크립트 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="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>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 파일 생성
위젯을 번들로 묶고 사용할 수 있는 .mpk를 생성하려면 Mendix 프로젝트에서 터미널에 다음 명령을 실행하세요.
npm run build
이 작업은 위젯 코드를 빌드한 다음 위젯을 위젯 폴더에 복사합니다. 마지막 단계는 Studio Pro에서 앱 디렉토리를 동기화하는 것입니다. F4를 누르거나 Studio Pro의 상단 메뉴에서 "앱" → "앱 디렉토리 동기화"로 이동합니다.
이제 Studio Pro에서 개발할 때 위젯에 액세스할 수 있습니다. 위젯은 컨텍스트를 위해 데이터뷰 내부에 배치해야 하며 정수 속성이 연결되어야 하지만 이를 설정한 후에는 Make it Native 9 앱을 사용하여 새 위젯을 실행하고 테스트할 수 있습니다.
플러그형 위젯 만들기에 대해 자세히 알아보세요
- https://docs.mendix.com/refguide/getting-the-make-it-native-app
- https://docs.mendix.com/howto/extensibility/create-a-pluggable-widget-one
- https://docs.mendix.com/howto/extensibility/create-a-pluggable-widget-two
- https://academy.mendix.com/link/path/108/Build-a-Pluggable-Widget
- https://docs.mendix.com/apidocs-mxsdk/apidocs/pluggable-widgets
- https://docs.mendix.com/apidocs-mxsdk/apidocs/client-apis-for-pluggable-widgets