mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-13 09:41:57 +00:00
test: 💍 完善 Rax 出码的示例, 解决 methods 的上下文绑定的问题
This commit is contained in:
parent
a1a3b68287
commit
6cd07524b6
@ -19,7 +19,11 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
||||
content: `import { createElement, Component } from 'rax';`,
|
||||
content: `
|
||||
// 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。
|
||||
// 例外:rax 框架的导出名和各种组件名除外。
|
||||
import { createElement, Component } from 'rax';
|
||||
`,
|
||||
linkAfter: [],
|
||||
});
|
||||
|
||||
|
||||
@ -67,6 +67,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
get props() {
|
||||
return self.props;
|
||||
},
|
||||
...this._methods,
|
||||
};
|
||||
|
||||
return context;
|
||||
|
||||
@ -32,7 +32,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
fileType: FileType.JSX,
|
||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
||||
content: `
|
||||
import { createDataSourceEngine } from '@ali/lowcode-datasource-engine';
|
||||
import { create as __$$createDataSourceEngine } from '@ali/lowcode-datasource-engine';
|
||||
`,
|
||||
linkAfter: [],
|
||||
});
|
||||
@ -43,7 +43,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
||||
content: `
|
||||
_dataSourceList = this._defineDataSourceList();
|
||||
_dataSourceEngine = createDataSourceEngine(this._dataSourceList, this._context);`,
|
||||
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceList, this._context);`,
|
||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
|
||||
});
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
name: RAX_CHUNK_NAME.MethodsBegin,
|
||||
content: `
|
||||
_defineMethods() {
|
||||
return ({
|
||||
const __$$methods = ({
|
||||
`,
|
||||
linkAfter: [RAX_CHUNK_NAME.ClassRenderEnd, CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod],
|
||||
});
|
||||
@ -55,6 +55,17 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
name: RAX_CHUNK_NAME.MethodsEnd,
|
||||
content: `
|
||||
});
|
||||
|
||||
// 为所有的方法绑定上下文
|
||||
Object.entries(__$$methods).forEach(([methodName, method]) => {
|
||||
if (typeof method === 'function') {
|
||||
__$$methods[methodName] = (...args) => {
|
||||
return method.apply(this._context, args);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return __$$methods;
|
||||
}
|
||||
`,
|
||||
linkAfter: [RAX_CHUNK_NAME.MethodsBegin, RAX_CHUNK_NAME.MethodsContent],
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
// 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。
|
||||
// 例外:rax 框架的导出名和各种组件名除外。
|
||||
import { createElement, Component } from 'rax';
|
||||
|
||||
import Page from 'rax-view';
|
||||
|
||||
import Text from 'rax-text';
|
||||
|
||||
import { createDataSourceEngine } from '@ali/lowcode-datasource-engine';
|
||||
import { create as __$$createDataSourceEngine } from '@ali/lowcode-datasource-engine';
|
||||
|
||||
import __$$projectUtils from '../../utils';
|
||||
|
||||
@ -16,7 +18,7 @@ class Home$$Page extends Component {
|
||||
_context = this._createContext();
|
||||
|
||||
_dataSourceList = this._defineDataSourceList();
|
||||
_dataSourceEngine = createDataSourceEngine(this._dataSourceList, this._context);
|
||||
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceList, this._context);
|
||||
|
||||
_utils = this._defineUtils();
|
||||
|
||||
@ -62,6 +64,7 @@ class Home$$Page extends Component {
|
||||
get props() {
|
||||
return self.props;
|
||||
},
|
||||
...this._methods,
|
||||
};
|
||||
|
||||
return context;
|
||||
@ -86,7 +89,18 @@ class Home$$Page extends Component {
|
||||
}
|
||||
|
||||
_defineMethods() {
|
||||
return {};
|
||||
const __$$methods = {};
|
||||
|
||||
// 为所有的方法绑定上下文
|
||||
Object.entries(__$$methods).forEach(([methodName, method]) => {
|
||||
if (typeof method === 'function') {
|
||||
__$$methods[methodName] = (...args) => {
|
||||
return method.apply(this._context, args);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return __$$methods;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,8 @@
|
||||
"rax-text": "^1.0.0",
|
||||
"rax-image": "^1.0.0",
|
||||
"moment": "*",
|
||||
"lodash": "*"
|
||||
"lodash": "*",
|
||||
"universal-toast": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"build-plugin-rax-app": "^5.0.0",
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
// 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。
|
||||
// 例外:rax 框架的导出名和各种组件名除外。
|
||||
import { createElement, Component } from 'rax';
|
||||
|
||||
import View from 'rax-view';
|
||||
@ -6,7 +8,7 @@ import Text from 'rax-text';
|
||||
|
||||
import Image from 'rax-image';
|
||||
|
||||
import { createDataSourceEngine } from '@ali/lowcode-datasource-engine';
|
||||
import { create as __$$createDataSourceEngine } from '@ali/lowcode-datasource-engine';
|
||||
|
||||
import __$$projectUtils from '../../utils';
|
||||
|
||||
@ -30,9 +32,11 @@ class Home$$Page extends Component {
|
||||
};
|
||||
|
||||
_methods = this._defineMethods();
|
||||
|
||||
_context = this._createContext();
|
||||
|
||||
_dataSourceList = this._defineDataSourceList();
|
||||
_dataSourceEngine = createDataSourceEngine(this._dataSourceList, this._context);
|
||||
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceList, this._context);
|
||||
|
||||
_utils = this._defineUtils();
|
||||
|
||||
@ -57,7 +61,7 @@ class Home$$Page extends Component {
|
||||
source={{ uri: __$$eval(() => __$$context.state.user.avatar) }}
|
||||
style={{ width: '32px', height: '32px' }}
|
||||
/>
|
||||
<View>
|
||||
<View onClick={__$$eval(() => __$$context.hello)}>
|
||||
<Text>{__$$eval(() => __$$context.state.user.name)}</Text>
|
||||
<Text>{__$$eval(() => __$$context.state.user.age)}岁</Text>
|
||||
</View>
|
||||
@ -67,7 +71,15 @@ class Home$$Page extends Component {
|
||||
<Text>=== Orders: ===</Text>
|
||||
</View>
|
||||
{__$$evalArray(() => __$$context.state.orders).map((item, index) => (
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<View
|
||||
style={{ flexDirection: 'row' }}
|
||||
onClick={__$$eval(
|
||||
() =>
|
||||
function () {
|
||||
__$$context.utils.recordEvent(`CLICK_ORDER`, item.title);
|
||||
},
|
||||
)}
|
||||
>
|
||||
<View>
|
||||
<Image source={{ uri: __$$eval(() => item.coverUrl) }} style={{ width: '80px', height: '60px' }} />
|
||||
</View>
|
||||
@ -77,6 +89,11 @@ class Home$$Page extends Component {
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
<View>
|
||||
<Text>操作提示:</Text>
|
||||
<Text>1. 点击会员名,可以弹出 Toast "Hello xxx!"</Text>
|
||||
<Text>2. 点击订单,会记录点击的订单信息,并弹出 Toast 提示</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@ -109,6 +126,7 @@ class Home$$Page extends Component {
|
||||
get props() {
|
||||
return self.props;
|
||||
},
|
||||
...this._methods,
|
||||
};
|
||||
|
||||
return context;
|
||||
@ -141,11 +159,23 @@ class Home$$Page extends Component {
|
||||
}
|
||||
|
||||
_defineMethods() {
|
||||
return {
|
||||
const __$$methods = {
|
||||
hello: function hello() {
|
||||
console.log('Hello world!');
|
||||
this.utils.Toast.show(`Hello ${this.state.user.name}!`);
|
||||
console.log(`Hello ${this.state.user.name}!`);
|
||||
},
|
||||
};
|
||||
|
||||
// 为所有的方法绑定上下文
|
||||
Object.entries(__$$methods).forEach(([methodName, method]) => {
|
||||
if (typeof method === 'function') {
|
||||
__$$methods[methodName] = (...args) => {
|
||||
return method.apply(this._context, args);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return __$$methods;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,14 +2,25 @@ import moment from 'moment';
|
||||
|
||||
import clone from 'lodash/clone';
|
||||
|
||||
import Toast from 'universal-toast';
|
||||
|
||||
const formatPrice = function formatPrice(price, unit) {
|
||||
return Number(price).toFixed(2) + unit;
|
||||
};
|
||||
|
||||
const recordEvent = function recordEvent(eventName, eventDetail) {
|
||||
this.utils.Toast.show(`[EVENT]: ${eventName} ${eventDetail}`);
|
||||
console.log(`[EVENT]: ${eventName} (detail: %o) (user: %o)`, eventDetail, this.state.user);
|
||||
};
|
||||
|
||||
export default {
|
||||
formatPrice,
|
||||
|
||||
recordEvent,
|
||||
|
||||
moment,
|
||||
|
||||
clone,
|
||||
|
||||
Toast,
|
||||
};
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
methods: {
|
||||
hello: {
|
||||
type: 'JSExpression',
|
||||
value: 'function hello(){ console.log("Hello world!"); }',
|
||||
value: 'function hello(){\n this.utils.Toast.show(`Hello ${this.state.user.name}!`);\n console.log(`Hello ${this.state.user.name}!`); }',
|
||||
},
|
||||
},
|
||||
dataSource: {
|
||||
@ -132,6 +132,12 @@
|
||||
},
|
||||
{
|
||||
componentName: 'View',
|
||||
props: {
|
||||
onClick: {
|
||||
type: 'JSFunction',
|
||||
value: 'this.hello',
|
||||
},
|
||||
},
|
||||
children: [
|
||||
{
|
||||
componentName: 'Text',
|
||||
@ -172,6 +178,10 @@
|
||||
},
|
||||
props: {
|
||||
style: { flexDirection: 'row' },
|
||||
onClick: {
|
||||
type: 'JSFunction',
|
||||
value: 'function(){ this.utils.recordEvent(`CLICK_ORDER`, this.item.title) }',
|
||||
},
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@ -215,10 +225,31 @@
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
componentName: 'View',
|
||||
children: [
|
||||
{
|
||||
componentName: 'Text',
|
||||
props: {},
|
||||
children: '操作提示:',
|
||||
},
|
||||
{
|
||||
componentName: 'Text',
|
||||
props: {},
|
||||
children: '1. 点击会员名,可以弹出 Toast "Hello xxx!"',
|
||||
},
|
||||
{
|
||||
componentName: 'Text',
|
||||
props: {},
|
||||
children: '2. 点击订单,会记录点击的订单信息,并弹出 Toast 提示',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
utils: [
|
||||
// 可以直接定义一个函数
|
||||
{
|
||||
name: 'formatPrice',
|
||||
type: 'function',
|
||||
@ -227,6 +258,16 @@
|
||||
value: 'function formatPrice(price, unit) { return Number(price).toFixed(2) + unit; }',
|
||||
},
|
||||
},
|
||||
// 在 utils 里面也可以用 this 访问当前上下文:
|
||||
{
|
||||
name: 'recordEvent',
|
||||
type: 'function',
|
||||
content: {
|
||||
type: 'JSFunction',
|
||||
value: 'function recordEvent(eventName, eventDetail) { \n this.utils.Toast.show(`[EVENT]: ${eventName} ${eventDetail}`);\n console.log(`[EVENT]: ${eventName} (detail: %o) (user: %o)`, eventDetail, this.state.user); }',
|
||||
},
|
||||
},
|
||||
// 也可以直接从 npm 包引入 (下例等价于 `import moment from 'moment';`)
|
||||
{
|
||||
name: 'moment',
|
||||
type: 'npm',
|
||||
@ -236,6 +277,7 @@
|
||||
exportName: 'moment',
|
||||
},
|
||||
},
|
||||
// 可以引入子目录(下例等价于 `import clone from 'lodash/clone';`)
|
||||
{
|
||||
name: 'clone',
|
||||
type: 'npm',
|
||||
@ -247,6 +289,16 @@
|
||||
main: '/clone',
|
||||
},
|
||||
},
|
||||
// 支持 TNPM
|
||||
{
|
||||
name: 'Toast',
|
||||
type: 'tnpm',
|
||||
content: {
|
||||
package: 'universal-toast',
|
||||
version: '^1.2.0',
|
||||
exportName: 'Toast', // TODO: 这个 exportName 是否可以省略?省略后默认是上一层的 name?
|
||||
},
|
||||
},
|
||||
],
|
||||
config: {
|
||||
sdkVersion: '1.0.3',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user