react-native-fxview 1.0.1 → 1.0.2-beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{FXViewCategoryController.d.ts → FXCategoryController.d.ts} +5 -5
- package/{FXViewCategoryController.js → FXCategoryController.js} +3 -3
- package/{FXViewCategoryController.ts → FXCategoryController.ts} +13 -10
- package/FXView.d.ts +2 -2
- package/FXView.js +1 -0
- package/FXView.tsx +3 -3
- package/FXViewController.d.ts +4 -4
- package/FXViewController.js +3 -2
- package/FXViewController.ts +14 -11
- package/FXViewManager.d.ts +8 -5
- package/FXViewManager.js +23 -13
- package/FXViewManager.ts +37 -19
- package/README.md +173 -25
- package/index.d.ts +1 -1
- package/index.js +3 -3
- package/index.ts +1 -1
- package/package.json +1 -1
- package/types.d.ts +6 -2
- package/types.ts +7 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
export declare class
|
|
2
|
+
import { FXComponentItem, FXComponentController } from "./types";
|
|
3
|
+
export declare class FXCategoryController {
|
|
4
4
|
fxViewId: string;
|
|
5
5
|
categoryId: string;
|
|
6
6
|
private updateCallback?;
|
|
@@ -13,14 +13,14 @@ export declare class FXViewCategoryController {
|
|
|
13
13
|
* @param componentId 可选的组件 ID
|
|
14
14
|
* @returns 组件控制器
|
|
15
15
|
*/
|
|
16
|
-
add(component: React.ReactNode, componentId?: string):
|
|
16
|
+
add(component: React.ReactNode, componentId?: string): FXComponentController;
|
|
17
17
|
/**
|
|
18
18
|
* 创建但不显示组件
|
|
19
19
|
* @param component 要创建的组件
|
|
20
20
|
* @param componentId 可选的组件 ID
|
|
21
21
|
* @returns 组件控制器
|
|
22
22
|
*/
|
|
23
|
-
build(component: React.ReactNode, componentId?: string):
|
|
23
|
+
build(component: React.ReactNode, componentId?: string): FXComponentController;
|
|
24
24
|
/**
|
|
25
25
|
* 显示已存在的组件
|
|
26
26
|
* @param componentId 组件 ID
|
|
@@ -59,7 +59,7 @@ export declare class FXViewCategoryController {
|
|
|
59
59
|
* 获取组件列表
|
|
60
60
|
* @returns 组件列表
|
|
61
61
|
*/
|
|
62
|
-
getComponents():
|
|
62
|
+
getComponents(): FXComponentItem[];
|
|
63
63
|
/**
|
|
64
64
|
* 获取组件数量
|
|
65
65
|
* @returns 组件数量
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.FXCategoryController = void 0;
|
|
4
4
|
const PriorityQueue_1 = require("./queue/PriorityQueue");
|
|
5
|
-
class
|
|
5
|
+
class FXCategoryController {
|
|
6
6
|
constructor(fxViewId, categoryId, triggerUpdate) {
|
|
7
7
|
// 存储组件的 Map 和优先队列
|
|
8
8
|
this.componentMap = new Map();
|
|
@@ -267,4 +267,4 @@ class FXViewCategoryController {
|
|
|
267
267
|
.substring(2, 9)}`;
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
|
-
exports.
|
|
270
|
+
exports.FXCategoryController = FXCategoryController;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { FXComponentItem, FXComponentController } from "./types";
|
|
3
3
|
import { HeapType, PriorityOrder, PriorityQueue } from "./queue/PriorityQueue";
|
|
4
4
|
|
|
5
|
-
export class
|
|
5
|
+
export class FXCategoryController {
|
|
6
6
|
public fxViewId: string;
|
|
7
7
|
public categoryId: string;
|
|
8
8
|
private updateCallback?: () => void;
|
|
9
9
|
|
|
10
10
|
// 存储组件的 Map 和优先队列
|
|
11
|
-
private componentMap: Map<string,
|
|
12
|
-
private componentQueue: PriorityQueue<
|
|
11
|
+
private componentMap: Map<string, FXComponentItem> = new Map();
|
|
12
|
+
private componentQueue: PriorityQueue<FXComponentItem> = new PriorityQueue(
|
|
13
13
|
HeapType.MAX_HEAP,
|
|
14
14
|
PriorityOrder.FIFO,
|
|
15
15
|
);
|
|
@@ -32,7 +32,7 @@ export class FXViewCategoryController {
|
|
|
32
32
|
* @param componentId 可选的组件 ID
|
|
33
33
|
* @returns 组件控制器
|
|
34
34
|
*/
|
|
35
|
-
add(component: React.ReactNode, componentId?: string):
|
|
35
|
+
add(component: React.ReactNode, componentId?: string): FXComponentController {
|
|
36
36
|
console.log(
|
|
37
37
|
`FXViewCategoryController.add`,
|
|
38
38
|
`[${this.categoryId}]`,
|
|
@@ -49,7 +49,7 @@ export class FXViewCategoryController {
|
|
|
49
49
|
this.remove(finalComponentId);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
const componentItem:
|
|
52
|
+
const componentItem: FXComponentItem = {
|
|
53
53
|
componentId: finalComponentId,
|
|
54
54
|
component,
|
|
55
55
|
visible: true, // add 方法默认可见
|
|
@@ -68,7 +68,10 @@ export class FXViewCategoryController {
|
|
|
68
68
|
* @param componentId 可选的组件 ID
|
|
69
69
|
* @returns 组件控制器
|
|
70
70
|
*/
|
|
71
|
-
build(
|
|
71
|
+
build(
|
|
72
|
+
component: React.ReactNode,
|
|
73
|
+
componentId?: string,
|
|
74
|
+
): FXComponentController {
|
|
72
75
|
console.log(
|
|
73
76
|
`FXViewCategoryController.build`,
|
|
74
77
|
`[${this.categoryId}]`,
|
|
@@ -85,7 +88,7 @@ export class FXViewCategoryController {
|
|
|
85
88
|
this.remove(finalComponentId);
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
const componentItem:
|
|
91
|
+
const componentItem: FXComponentItem = {
|
|
89
92
|
componentId: finalComponentId,
|
|
90
93
|
component,
|
|
91
94
|
visible: false, // build 方法默认不可见
|
|
@@ -270,7 +273,7 @@ export class FXViewCategoryController {
|
|
|
270
273
|
* 获取组件列表
|
|
271
274
|
* @returns 组件列表
|
|
272
275
|
*/
|
|
273
|
-
getComponents():
|
|
276
|
+
getComponents(): FXComponentItem[] {
|
|
274
277
|
return this.componentQueue.getAll();
|
|
275
278
|
}
|
|
276
279
|
|
|
@@ -331,7 +334,7 @@ export class FXViewCategoryController {
|
|
|
331
334
|
* @param componentId 组件 ID
|
|
332
335
|
* @returns 组件控制器
|
|
333
336
|
*/
|
|
334
|
-
private createController(componentId: string):
|
|
337
|
+
private createController(componentId: string): FXComponentController {
|
|
335
338
|
console.log(
|
|
336
339
|
`FXViewCategoryController.createController`,
|
|
337
340
|
`[${this.categoryId}]`,
|
package/FXView.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React, { Component } from "react";
|
|
2
2
|
import { ViewProps } from "react-native";
|
|
3
|
-
import {
|
|
3
|
+
import { FXComponentItem } from "./types";
|
|
4
4
|
interface FXViewProps extends ViewProps {
|
|
5
5
|
fxViewId?: string;
|
|
6
6
|
}
|
|
7
7
|
interface FXViewState {
|
|
8
|
-
components:
|
|
8
|
+
components: FXComponentItem[];
|
|
9
9
|
}
|
|
10
10
|
export default class FXView extends Component<FXViewProps, FXViewState> {
|
|
11
11
|
state: FXViewState;
|
package/FXView.js
CHANGED
|
@@ -74,6 +74,7 @@ class FXView extends react_1.Component {
|
|
|
74
74
|
const newViewId = this.props.fxViewId || this.viewId;
|
|
75
75
|
if (newViewId !== this.viewId) {
|
|
76
76
|
// ID 变化时重新注册
|
|
77
|
+
console.log("FXView updated changed", this.viewId);
|
|
77
78
|
FXViewManager_1.FXViewManager.getInstance().unregisterView(this.viewId);
|
|
78
79
|
this.viewId = newViewId;
|
|
79
80
|
FXViewManager_1.FXViewManager.getInstance().registerView(this.viewId, this.updateComponents);
|
package/FXView.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { Component } from "react";
|
|
2
2
|
import { View, ViewProps } from "react-native";
|
|
3
|
-
import {
|
|
3
|
+
import { FXComponentItem } from "./types";
|
|
4
4
|
import { FXViewManager } from "./FXViewManager";
|
|
5
5
|
|
|
6
6
|
interface FXViewProps extends ViewProps {
|
|
@@ -8,7 +8,7 @@ interface FXViewProps extends ViewProps {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
interface FXViewState {
|
|
11
|
-
components:
|
|
11
|
+
components: FXComponentItem[];
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export default class FXView extends Component<FXViewProps, FXViewState> {
|
|
@@ -43,8 +43,8 @@ export default class FXView extends Component<FXViewProps, FXViewState> {
|
|
|
43
43
|
|
|
44
44
|
if (newViewId !== this.viewId) {
|
|
45
45
|
// ID 变化时重新注册
|
|
46
|
+
console.log("FXView updated changed", this.viewId);
|
|
46
47
|
FXViewManager.getInstance().unregisterView(this.viewId);
|
|
47
|
-
|
|
48
48
|
this.viewId = newViewId;
|
|
49
49
|
|
|
50
50
|
FXViewManager.getInstance().registerView(
|
package/FXViewController.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { FXComponentController, FXComponentItem } from "./types";
|
|
3
3
|
export declare class FXViewController {
|
|
4
4
|
fxViewId: string;
|
|
5
5
|
updateCallback?: () => void;
|
|
@@ -12,7 +12,7 @@ export declare class FXViewController {
|
|
|
12
12
|
* @param componentId 组件 ID(可选,自动生成)
|
|
13
13
|
* @returns 组件控制器
|
|
14
14
|
*/
|
|
15
|
-
add(component: React.ReactNode, categoryId?: string, componentId?: string):
|
|
15
|
+
add(component: React.ReactNode, categoryId?: string, componentId?: string): FXComponentController;
|
|
16
16
|
/**
|
|
17
17
|
* 创建但不显示组件
|
|
18
18
|
* @param component 组件内容
|
|
@@ -20,7 +20,7 @@ export declare class FXViewController {
|
|
|
20
20
|
* @param componentId 组件 ID(可选,自动生成)
|
|
21
21
|
* @returns 组件控制器
|
|
22
22
|
*/
|
|
23
|
-
build(component: React.ReactNode, categoryId?: string, componentId?: string):
|
|
23
|
+
build(component: React.ReactNode, categoryId?: string, componentId?: string): FXComponentController;
|
|
24
24
|
/**
|
|
25
25
|
* 显示已存在的组件
|
|
26
26
|
* @param componentId 组件 ID
|
|
@@ -70,7 +70,7 @@ export declare class FXViewController {
|
|
|
70
70
|
* @param filterOptions 过滤选项
|
|
71
71
|
* @returns 组件列表
|
|
72
72
|
*/
|
|
73
|
-
getComponents(categoryId?: string):
|
|
73
|
+
getComponents(categoryId?: string): FXComponentItem[];
|
|
74
74
|
/**
|
|
75
75
|
* 获取总组件数量
|
|
76
76
|
* @returns 组件数量
|
package/FXViewController.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FXViewController = void 0;
|
|
4
|
-
const
|
|
4
|
+
const FXCategoryController_1 = require("./FXCategoryController");
|
|
5
5
|
class FXViewController {
|
|
6
6
|
constructor(fxViewId) {
|
|
7
7
|
// 存储各分类的控制器
|
|
@@ -140,6 +140,7 @@ class FXViewController {
|
|
|
140
140
|
controller.clearAll();
|
|
141
141
|
});
|
|
142
142
|
this.categoryControllerMap.clear();
|
|
143
|
+
console.log("FXViewController.clearAll done", this.categoryControllerMap.size);
|
|
143
144
|
}
|
|
144
145
|
/**
|
|
145
146
|
* 清空指定分类的所有组件
|
|
@@ -268,7 +269,7 @@ class FXViewController {
|
|
|
268
269
|
const finalCategoryId = categoryId || "default";
|
|
269
270
|
let categoryController = this.categoryControllerMap.get(finalCategoryId);
|
|
270
271
|
if (!categoryController) {
|
|
271
|
-
categoryController = new
|
|
272
|
+
categoryController = new FXCategoryController_1.FXCategoryController(this.fxViewId, finalCategoryId, this.updateCallback);
|
|
272
273
|
this.categoryControllerMap.set(finalCategoryId, categoryController);
|
|
273
274
|
}
|
|
274
275
|
return categoryController;
|
package/FXViewController.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { FXComponentController, FXComponentItem } from "./types";
|
|
3
|
+
import { FXCategoryController } from "./FXCategoryController";
|
|
4
4
|
|
|
5
5
|
export class FXViewController {
|
|
6
6
|
public fxViewId: string;
|
|
7
7
|
public updateCallback?: () => void;
|
|
8
8
|
|
|
9
9
|
// 存储各分类的控制器
|
|
10
|
-
private categoryControllerMap: Map<string,
|
|
11
|
-
new Map();
|
|
10
|
+
private categoryControllerMap: Map<string, FXCategoryController> = new Map();
|
|
12
11
|
|
|
13
12
|
constructor(fxViewId: string) {
|
|
14
13
|
this.fxViewId = fxViewId;
|
|
@@ -27,7 +26,7 @@ export class FXViewController {
|
|
|
27
26
|
component: React.ReactNode,
|
|
28
27
|
categoryId?: string,
|
|
29
28
|
componentId?: string,
|
|
30
|
-
):
|
|
29
|
+
): FXComponentController {
|
|
31
30
|
console.log("FXViewController.add", `[${this.fxViewId}]`, {
|
|
32
31
|
categoryId,
|
|
33
32
|
componentId,
|
|
@@ -48,7 +47,7 @@ export class FXViewController {
|
|
|
48
47
|
component: React.ReactNode,
|
|
49
48
|
categoryId?: string,
|
|
50
49
|
componentId?: string,
|
|
51
|
-
):
|
|
50
|
+
): FXComponentController {
|
|
52
51
|
console.log("FXViewController.build", `[${this.fxViewId}]`, {
|
|
53
52
|
categoryId,
|
|
54
53
|
componentId,
|
|
@@ -191,6 +190,10 @@ export class FXViewController {
|
|
|
191
190
|
controller.clearAll();
|
|
192
191
|
});
|
|
193
192
|
this.categoryControllerMap.clear();
|
|
193
|
+
console.log(
|
|
194
|
+
"FXViewController.clearAll done",
|
|
195
|
+
this.categoryControllerMap.size,
|
|
196
|
+
);
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
/**
|
|
@@ -233,8 +236,8 @@ export class FXViewController {
|
|
|
233
236
|
* @param filterOptions 过滤选项
|
|
234
237
|
* @returns 组件列表
|
|
235
238
|
*/
|
|
236
|
-
getComponents(categoryId?: string):
|
|
237
|
-
const result:
|
|
239
|
+
getComponents(categoryId?: string): FXComponentItem[] {
|
|
240
|
+
const result: FXComponentItem[] = [];
|
|
238
241
|
|
|
239
242
|
this.categoryControllerMap.forEach((categoryController, category) => {
|
|
240
243
|
// 如果指定了类别,只处理指定类别
|
|
@@ -325,7 +328,7 @@ export class FXViewController {
|
|
|
325
328
|
*/
|
|
326
329
|
private getCategoryController(
|
|
327
330
|
categoryId?: string,
|
|
328
|
-
):
|
|
331
|
+
): FXCategoryController | null {
|
|
329
332
|
const finalCategoryId = categoryId || "default";
|
|
330
333
|
return this.categoryControllerMap.get(finalCategoryId) || null;
|
|
331
334
|
}
|
|
@@ -337,13 +340,13 @@ export class FXViewController {
|
|
|
337
340
|
*/
|
|
338
341
|
private getCategoryControllerOrCreate(
|
|
339
342
|
categoryId?: string,
|
|
340
|
-
):
|
|
343
|
+
): FXCategoryController {
|
|
341
344
|
const finalCategoryId = categoryId || "default";
|
|
342
345
|
|
|
343
346
|
let categoryController = this.categoryControllerMap.get(finalCategoryId);
|
|
344
347
|
|
|
345
348
|
if (!categoryController) {
|
|
346
|
-
categoryController = new
|
|
349
|
+
categoryController = new FXCategoryController(
|
|
347
350
|
this.fxViewId,
|
|
348
351
|
finalCategoryId,
|
|
349
352
|
this.updateCallback,
|
package/FXViewManager.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { FXComponentController, FXComponentItem, FXLifecycleCallbacks } from "./types";
|
|
3
3
|
import { FXViewController } from "./FXViewController";
|
|
4
4
|
export declare class FXViewManager {
|
|
5
5
|
private static instance;
|
|
6
6
|
private viewControllerMap;
|
|
7
|
-
private
|
|
7
|
+
private fxViewIdQueue;
|
|
8
|
+
private viewLifecycleCallbacks;
|
|
8
9
|
static getInstance(): FXViewManager;
|
|
9
10
|
/**
|
|
10
11
|
* 创建并显示组件
|
|
@@ -14,7 +15,7 @@ export declare class FXViewManager {
|
|
|
14
15
|
* @param componentId 组件 ID(可选,自动生成)
|
|
15
16
|
* @returns 组件控制器
|
|
16
17
|
*/
|
|
17
|
-
add(component: React.ReactNode, fxViewId?: string, categoryId?: string, componentId?: string):
|
|
18
|
+
add(component: React.ReactNode, fxViewId?: string, categoryId?: string, componentId?: string): FXComponentController;
|
|
18
19
|
/**
|
|
19
20
|
* 创建但不显示组件
|
|
20
21
|
* @param component 组件内容
|
|
@@ -23,7 +24,7 @@ export declare class FXViewManager {
|
|
|
23
24
|
* @param componentId 组件 ID(可选,自动生成)
|
|
24
25
|
* @returns 组件控制器
|
|
25
26
|
*/
|
|
26
|
-
build(component: React.ReactNode, fxViewId?: string, categoryId?: string, componentId?: string):
|
|
27
|
+
build(component: React.ReactNode, fxViewId?: string, categoryId?: string, componentId?: string): FXComponentController;
|
|
27
28
|
/**
|
|
28
29
|
* 显示已存在的组件
|
|
29
30
|
* @param componentId 组件 ID
|
|
@@ -83,6 +84,8 @@ export declare class FXViewManager {
|
|
|
83
84
|
* @returns 是否成功注销
|
|
84
85
|
*/
|
|
85
86
|
unregisterView(fxViewId: string): boolean;
|
|
87
|
+
registerLifecycleCallbacks(callbacks: FXLifecycleCallbacks): void;
|
|
88
|
+
unregisterLifecycleCallbacks(callbacks: FXLifecycleCallbacks): void;
|
|
86
89
|
/**
|
|
87
90
|
* 获取最近使用的视图 ID(栈顶)
|
|
88
91
|
* @returns 最近的视图 ID 或 null
|
|
@@ -94,7 +97,7 @@ export declare class FXViewManager {
|
|
|
94
97
|
* @param categoryId 分类 ID(可选)
|
|
95
98
|
* @returns 组件列表
|
|
96
99
|
*/
|
|
97
|
-
getComponents(fxViewId?: string, categoryId?: string):
|
|
100
|
+
getComponents(fxViewId?: string, categoryId?: string): FXComponentItem[];
|
|
98
101
|
/**
|
|
99
102
|
* 获取组件数量
|
|
100
103
|
* @param fxViewId 视图 ID(可选,使用最近的视图)
|
package/FXViewManager.js
CHANGED
|
@@ -7,7 +7,8 @@ class FXViewManager {
|
|
|
7
7
|
constructor() {
|
|
8
8
|
// 存储视图控制器
|
|
9
9
|
this.viewControllerMap = new Map();
|
|
10
|
-
this.
|
|
10
|
+
this.fxViewIdQueue = new PriorityQueue_1.PriorityQueue(PriorityQueue_1.HeapType.MAX_HEAP, PriorityQueue_1.PriorityOrder.LIFO);
|
|
11
|
+
this.viewLifecycleCallbacks = [];
|
|
11
12
|
//#endregion
|
|
12
13
|
}
|
|
13
14
|
static getInstance() {
|
|
@@ -196,14 +197,12 @@ class FXViewManager {
|
|
|
196
197
|
}
|
|
197
198
|
// 注册更新回调
|
|
198
199
|
viewController.registerUpdateCallback(updateCallback);
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
this.viewControllerQueue.enqueue(viewController);
|
|
200
|
+
this.fxViewIdQueue.remove(fxViewId);
|
|
201
|
+
this.fxViewIdQueue.enqueue(fxViewId);
|
|
202
|
+
this.viewLifecycleCallbacks.forEach((callback) => {
|
|
203
|
+
var _a;
|
|
204
|
+
(_a = callback.didMount) === null || _a === void 0 ? void 0 : _a.call(callback, fxViewId);
|
|
205
|
+
});
|
|
207
206
|
return viewController;
|
|
208
207
|
}
|
|
209
208
|
/**
|
|
@@ -223,18 +222,29 @@ class FXViewManager {
|
|
|
223
222
|
// 清空所有组件
|
|
224
223
|
viewController.clearAll();
|
|
225
224
|
// 从队列中移除
|
|
226
|
-
this.
|
|
225
|
+
this.fxViewIdQueue.remove(fxViewId);
|
|
227
226
|
// 从 Map 中删除
|
|
228
227
|
this.viewControllerMap.delete(fxViewId);
|
|
228
|
+
this.viewLifecycleCallbacks.forEach((callback) => {
|
|
229
|
+
var _a;
|
|
230
|
+
(_a = callback.willUnmount) === null || _a === void 0 ? void 0 : _a.call(callback, fxViewId);
|
|
231
|
+
});
|
|
229
232
|
return true;
|
|
230
233
|
}
|
|
234
|
+
registerLifecycleCallbacks(callbacks) {
|
|
235
|
+
console.log("FXViewManager.registerLifecycleCallbacks");
|
|
236
|
+
this.viewLifecycleCallbacks.push(callbacks);
|
|
237
|
+
}
|
|
238
|
+
unregisterLifecycleCallbacks(callbacks) {
|
|
239
|
+
console.log("FXViewManager.unregisterLifecycleCallbacks");
|
|
240
|
+
this.viewLifecycleCallbacks = this.viewLifecycleCallbacks.filter((callback) => callback !== callbacks);
|
|
241
|
+
}
|
|
231
242
|
/**
|
|
232
243
|
* 获取最近使用的视图 ID(栈顶)
|
|
233
244
|
* @returns 最近的视图 ID 或 null
|
|
234
245
|
*/
|
|
235
246
|
getLatestFXViewId() {
|
|
236
|
-
|
|
237
|
-
return ((_a = this.viewControllerQueue.peek()) === null || _a === void 0 ? void 0 : _a.fxViewId) || null;
|
|
247
|
+
return this.fxViewIdQueue.peek() || null;
|
|
238
248
|
}
|
|
239
249
|
/**
|
|
240
250
|
* 获取组件列表
|
|
@@ -327,7 +337,7 @@ class FXViewManager {
|
|
|
327
337
|
console.warn(`FXViewController ${finalFXViewId} not registered, creating a temporary one`);
|
|
328
338
|
viewController = new FXViewController_1.FXViewController(finalFXViewId);
|
|
329
339
|
this.viewControllerMap.set(finalFXViewId, viewController);
|
|
330
|
-
this.
|
|
340
|
+
this.fxViewIdQueue.enqueue(finalFXViewId);
|
|
331
341
|
}
|
|
332
342
|
return viewController;
|
|
333
343
|
}
|
package/FXViewManager.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
FXComponentController,
|
|
4
|
+
FXComponentItem,
|
|
5
|
+
FXLifecycleCallbacks,
|
|
6
|
+
} from "./types";
|
|
3
7
|
import { FXViewController } from "./FXViewController";
|
|
4
8
|
import { HeapType, PriorityOrder, PriorityQueue } from "./queue/PriorityQueue";
|
|
5
9
|
|
|
@@ -8,8 +12,11 @@ export class FXViewManager {
|
|
|
8
12
|
|
|
9
13
|
// 存储视图控制器
|
|
10
14
|
private viewControllerMap: Map<string, FXViewController> = new Map();
|
|
11
|
-
private
|
|
12
|
-
|
|
15
|
+
private fxViewIdQueue: PriorityQueue<string> = new PriorityQueue(
|
|
16
|
+
HeapType.MAX_HEAP,
|
|
17
|
+
PriorityOrder.LIFO,
|
|
18
|
+
);
|
|
19
|
+
private viewLifecycleCallbacks: Array<FXLifecycleCallbacks> = [];
|
|
13
20
|
|
|
14
21
|
static getInstance(): FXViewManager {
|
|
15
22
|
if (!FXViewManager.instance) {
|
|
@@ -33,7 +40,7 @@ export class FXViewManager {
|
|
|
33
40
|
fxViewId?: string,
|
|
34
41
|
categoryId?: string,
|
|
35
42
|
componentId?: string,
|
|
36
|
-
):
|
|
43
|
+
): FXComponentController {
|
|
37
44
|
console.log("FXViewManager.add", {
|
|
38
45
|
fxViewId,
|
|
39
46
|
categoryId,
|
|
@@ -57,7 +64,7 @@ export class FXViewManager {
|
|
|
57
64
|
fxViewId?: string,
|
|
58
65
|
categoryId?: string,
|
|
59
66
|
componentId?: string,
|
|
60
|
-
):
|
|
67
|
+
): FXComponentController {
|
|
61
68
|
console.log("FXViewManager.build", {
|
|
62
69
|
fxViewId,
|
|
63
70
|
categoryId,
|
|
@@ -242,16 +249,11 @@ export class FXViewManager {
|
|
|
242
249
|
|
|
243
250
|
// 注册更新回调
|
|
244
251
|
viewController.registerUpdateCallback(updateCallback);
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
.
|
|
249
|
-
|
|
250
|
-
if (existingController) {
|
|
251
|
-
this.viewControllerQueue.remove(existingController);
|
|
252
|
-
}
|
|
253
|
-
this.viewControllerQueue.enqueue(viewController);
|
|
254
|
-
|
|
252
|
+
this.fxViewIdQueue.remove(fxViewId);
|
|
253
|
+
this.fxViewIdQueue.enqueue(fxViewId);
|
|
254
|
+
this.viewLifecycleCallbacks.forEach((callback) => {
|
|
255
|
+
callback.didMount?.(fxViewId);
|
|
256
|
+
});
|
|
255
257
|
return viewController;
|
|
256
258
|
}
|
|
257
259
|
|
|
@@ -276,20 +278,36 @@ export class FXViewManager {
|
|
|
276
278
|
viewController.clearAll();
|
|
277
279
|
|
|
278
280
|
// 从队列中移除
|
|
279
|
-
this.
|
|
281
|
+
this.fxViewIdQueue.remove(fxViewId);
|
|
280
282
|
|
|
281
283
|
// 从 Map 中删除
|
|
282
284
|
this.viewControllerMap.delete(fxViewId);
|
|
283
285
|
|
|
286
|
+
this.viewLifecycleCallbacks.forEach((callback) => {
|
|
287
|
+
callback.willUnmount?.(fxViewId);
|
|
288
|
+
});
|
|
289
|
+
|
|
284
290
|
return true;
|
|
285
291
|
}
|
|
286
292
|
|
|
293
|
+
registerLifecycleCallbacks(callbacks: FXLifecycleCallbacks): void {
|
|
294
|
+
console.log("FXViewManager.registerLifecycleCallbacks");
|
|
295
|
+
this.viewLifecycleCallbacks.push(callbacks);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
unregisterLifecycleCallbacks(callbacks: FXLifecycleCallbacks): void {
|
|
299
|
+
console.log("FXViewManager.unregisterLifecycleCallbacks");
|
|
300
|
+
this.viewLifecycleCallbacks = this.viewLifecycleCallbacks.filter(
|
|
301
|
+
(callback) => callback !== callbacks,
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
287
305
|
/**
|
|
288
306
|
* 获取最近使用的视图 ID(栈顶)
|
|
289
307
|
* @returns 最近的视图 ID 或 null
|
|
290
308
|
*/
|
|
291
309
|
getLatestFXViewId(): string | null {
|
|
292
|
-
return this.
|
|
310
|
+
return this.fxViewIdQueue.peek() || null;
|
|
293
311
|
}
|
|
294
312
|
|
|
295
313
|
/**
|
|
@@ -298,7 +316,7 @@ export class FXViewManager {
|
|
|
298
316
|
* @param categoryId 分类 ID(可选)
|
|
299
317
|
* @returns 组件列表
|
|
300
318
|
*/
|
|
301
|
-
getComponents(fxViewId?: string, categoryId?: string):
|
|
319
|
+
getComponents(fxViewId?: string, categoryId?: string): FXComponentItem[] {
|
|
302
320
|
console.log("FXViewManager.getComponents", { fxViewId, categoryId });
|
|
303
321
|
|
|
304
322
|
const finalFXViewId = fxViewId || this.getLatestFXViewId();
|
|
@@ -403,7 +421,7 @@ export class FXViewManager {
|
|
|
403
421
|
);
|
|
404
422
|
viewController = new FXViewController(finalFXViewId);
|
|
405
423
|
this.viewControllerMap.set(finalFXViewId, viewController);
|
|
406
|
-
this.
|
|
424
|
+
this.fxViewIdQueue.enqueue(finalFXViewId);
|
|
407
425
|
}
|
|
408
426
|
|
|
409
427
|
return viewController;
|
package/README.md
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
# React Native FXView
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
一个革命性的React Native动态UI预埋框架,支持在任何位置预埋容器,然后通过全局管理器在运行时动态注入和控制React组件。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 🎯 核心概念
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- 🔄 运行时UI更新
|
|
9
|
-
- 📂 组件分类管理
|
|
10
|
-
- 👁️ 组件显示/隐藏控制
|
|
11
|
-
- 🚀 轻量级和高性能
|
|
7
|
+
FXView采用**预埋+注入**的设计模式:
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
1. **预埋容器**:在应用的任何位置预埋`FXView`容器
|
|
10
|
+
2. **动态注入**:通过`FXViewManager`在任何时间、任何位置动态注入React组件
|
|
11
|
+
3. **全局控制**:支持跨组件、跨页面的全局UI管理和状态控制
|
|
12
|
+
|
|
13
|
+
## ✨ 功能特性
|
|
14
|
+
|
|
15
|
+
- 🎯 **动态组件注入** - 运行时在任何预埋位置注入React组件
|
|
16
|
+
- 🔄 **实时UI更新** - 支持组件内容的实时更新和状态管理
|
|
17
|
+
- 📂 **智能分类管理** - 按分类组织和管理动态组件
|
|
18
|
+
- 👁️ **显示/隐藏控制** - 灵活控制组件的显示状态
|
|
19
|
+
- 🌍 **全局访问** - 从应用的任何地方访问和管理UI
|
|
20
|
+
- 🚀 **轻量级高性能** - 优化的渲染性能和内存管理
|
|
21
|
+
|
|
22
|
+
## 📦 安装
|
|
14
23
|
|
|
15
24
|
```bash
|
|
16
25
|
npm install react-native-fxview
|
|
@@ -18,44 +27,183 @@ npm install react-native-fxview
|
|
|
18
27
|
yarn add react-native-fxview
|
|
19
28
|
```
|
|
20
29
|
|
|
21
|
-
## 快速开始
|
|
30
|
+
## 🚀 快速开始
|
|
31
|
+
|
|
32
|
+
### 1. 预埋FXView容器
|
|
33
|
+
|
|
34
|
+
在任何需要动态注入UI的位置预埋FXView:
|
|
22
35
|
|
|
23
36
|
```javascript
|
|
24
37
|
import React from 'react';
|
|
25
|
-
import { Text } from 'react-native';
|
|
38
|
+
import { View, Text } from 'react-native';
|
|
26
39
|
import { FXView } from 'react-native-fxview';
|
|
27
40
|
|
|
28
41
|
export default function App() {
|
|
29
42
|
return (
|
|
30
|
-
<
|
|
31
|
-
<Text
|
|
32
|
-
|
|
43
|
+
<View style={{ flex: 1 }}>
|
|
44
|
+
<Text>静态内容</Text>
|
|
45
|
+
|
|
46
|
+
{/* 预埋动态UI容器 */}
|
|
47
|
+
<FXView fxViewId="headerArea" style={{ height: 60 }} />
|
|
48
|
+
|
|
49
|
+
<Text>更多静态内容</Text>
|
|
50
|
+
|
|
51
|
+
{/* 在底部预埋另一个容器 */}
|
|
52
|
+
<FXView fxViewId="bottomSheet" style={{ position: 'absolute', bottom: 0 }} />
|
|
53
|
+
</View>
|
|
33
54
|
);
|
|
34
55
|
}
|
|
35
56
|
```
|
|
36
57
|
|
|
37
|
-
|
|
58
|
+
### 2. 动态注入组件
|
|
59
|
+
|
|
60
|
+
从应用的任何地方(甚至不同的页面或组件)动态注入UI:
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
import { FXViewManager } from 'react-native-fxview';
|
|
64
|
+
import { Button, View, Text } from 'react-native';
|
|
65
|
+
|
|
66
|
+
// 在headerArea注入一个搜索栏
|
|
67
|
+
const searchBarController = FXViewManager.getInstance().add(
|
|
68
|
+
<View style={{ backgroundColor: '#f0f0f0', padding: 10 }}>
|
|
69
|
+
<Text>搜索栏组件</Text>
|
|
70
|
+
</View>,
|
|
71
|
+
'headerArea', // fxViewId
|
|
72
|
+
'navigation' // categoryId
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// 在bottomSheet注入一个弹窗
|
|
76
|
+
const sheetController = FXViewManager.getInstance().add(
|
|
77
|
+
<View style={{ backgroundColor: 'white', padding: 20, borderRadius: 10 }}>
|
|
78
|
+
<Text>底部弹窗内容</Text>
|
|
79
|
+
<Button title="关闭" onPress={() => sheetController.hide()} />
|
|
80
|
+
</View>,
|
|
81
|
+
'bottomSheet',
|
|
82
|
+
'modals'
|
|
83
|
+
);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 3. 运行时控制
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
// 隐藏搜索栏
|
|
90
|
+
searchBarController.hide();
|
|
91
|
+
|
|
92
|
+
// 更新搜索栏内容
|
|
93
|
+
searchBarController.update(
|
|
94
|
+
<View style={{ backgroundColor: 'blue', padding: 10 }}>
|
|
95
|
+
<Text style={{ color: 'white' }}>更新后的搜索栏</Text>
|
|
96
|
+
</View>
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// 显示搜索栏
|
|
100
|
+
searchBarController.show();
|
|
101
|
+
|
|
102
|
+
// 完全移除组件
|
|
103
|
+
searchBarController.remove();
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 📖 API 参考
|
|
38
107
|
|
|
39
108
|
### FXView Props
|
|
40
109
|
|
|
41
|
-
- `fxViewId` (string, optional):
|
|
110
|
+
- `fxViewId` (string, optional): 容器唯一标识符,用于后续注入组件时的定位
|
|
111
|
+
|
|
112
|
+
### FXViewManager 主要方法
|
|
113
|
+
|
|
114
|
+
#### 组件管理
|
|
115
|
+
- `add(component, fxViewId?, category?, componentId?)` - 创建并显示组件
|
|
116
|
+
- `build(component, fxViewId?, category?, componentId?)` - 创建但不显示组件
|
|
117
|
+
- `show(componentId, fxViewId?, category?)` - 显示已存在的组件
|
|
118
|
+
- `hide(componentId, fxViewId?, category?)` - 隐藏组件
|
|
119
|
+
- `update(componentId, newComponent, fxViewId?, category?)` - 更新组件内容
|
|
120
|
+
- `remove(componentId, fxViewId?, category?)` - 移除组件
|
|
121
|
+
|
|
122
|
+
#### 批量操作
|
|
123
|
+
- `clearAll(fxViewId?)` - 清空指定或所有容器
|
|
124
|
+
- `clearCategory(categoryId, fxViewId?)` - 清空指定分类
|
|
125
|
+
|
|
126
|
+
#### 查询方法
|
|
127
|
+
- `getComponents(fxViewId?, category?)` - 获取组件列表
|
|
128
|
+
- `hasComponent(componentId, fxViewId?, category?)` - 检查组件是否存在
|
|
129
|
+
- `isComponentVisible(componentId, fxViewId?, category?)` - 检查组件是否可见
|
|
42
130
|
|
|
43
|
-
###
|
|
131
|
+
### 组件控制器 (FXComponentController)
|
|
44
132
|
|
|
45
|
-
|
|
133
|
+
- `show()` - 显示组件
|
|
134
|
+
- `hide()` - 隐藏组件
|
|
135
|
+
- `remove()` - 移除组件
|
|
136
|
+
- `update(newComponent)` - 更新组件内容
|
|
137
|
+
- `isVisible()` - 获取可见状态
|
|
138
|
+
- `exists()` - 检查组件是否存在
|
|
46
139
|
|
|
47
|
-
|
|
140
|
+
## 💡 使用场景
|
|
48
141
|
|
|
49
|
-
|
|
142
|
+
### 1. 动态导航栏
|
|
143
|
+
在不同页面根据状态动态改变顶部导航栏内容
|
|
50
144
|
|
|
51
|
-
###
|
|
145
|
+
### 2. 全局弹窗系统
|
|
146
|
+
从任何地方触发全局弹窗、通知、确认框等
|
|
52
147
|
|
|
53
|
-
|
|
148
|
+
### 3. 动态表单
|
|
149
|
+
根据用户操作动态添加、移除、更新表单字段
|
|
54
150
|
|
|
55
|
-
|
|
151
|
+
### 4. 插件化UI
|
|
152
|
+
支持第三方插件动态注入UI组件到主应用
|
|
56
153
|
|
|
57
|
-
|
|
154
|
+
### 5. A/B测试
|
|
155
|
+
动态切换不同的UI组件进行A/B测试
|
|
156
|
+
|
|
157
|
+
## 🎯 最佳实践
|
|
158
|
+
|
|
159
|
+
### 分类管理
|
|
160
|
+
使用分类来组织不同类型的动态组件:
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
// 导航相关
|
|
164
|
+
FXViewManager.getInstance().add(navComponent, 'header', 'navigation');
|
|
165
|
+
|
|
166
|
+
// 弹窗相关
|
|
167
|
+
FXViewManager.getInstance().add(modalComponent, 'overlay', 'modals');
|
|
168
|
+
|
|
169
|
+
// 通知相关
|
|
170
|
+
FXViewManager.getInstance().add(toastComponent, 'notification', 'notifications');
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 生命周期管理
|
|
174
|
+
```javascript
|
|
175
|
+
// 创建时
|
|
176
|
+
const controller = FXViewManager.getInstance().build(component, 'container');
|
|
177
|
+
|
|
178
|
+
// 需要时显示
|
|
179
|
+
controller.show();
|
|
180
|
+
|
|
181
|
+
// 不需要时隐藏
|
|
182
|
+
controller.hide();
|
|
183
|
+
|
|
184
|
+
// 完全清理
|
|
185
|
+
controller.remove();
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## 🔧 高级用法
|
|
189
|
+
|
|
190
|
+
### 生命周期回调
|
|
191
|
+
```javascript
|
|
192
|
+
FXViewManager.getInstance().registerLifecycleCallbacks({
|
|
193
|
+
didMount: (fxViewId) => console.log('FXView挂载:', fxViewId),
|
|
194
|
+
willUnmount: (fxViewId) => console.log('FXView卸载:', fxViewId)
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 组件查询和批量操作
|
|
199
|
+
```javascript
|
|
200
|
+
// 获取所有导航组件
|
|
201
|
+
const navComponents = FXViewManager.getInstance().getComponents(null, 'navigation');
|
|
202
|
+
|
|
203
|
+
// 清空所有弹窗
|
|
204
|
+
FXViewManager.getInstance().clearCategory('modals');
|
|
205
|
+
```
|
|
58
206
|
|
|
59
|
-
## 许可证
|
|
207
|
+
## 📄 许可证
|
|
60
208
|
|
|
61
|
-
MIT
|
|
209
|
+
MIT
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default as FXView } from "./FXView";
|
|
2
2
|
export { FXViewManager } from "./FXViewManager";
|
|
3
3
|
export { FXViewController } from "./FXViewController";
|
|
4
|
-
export {
|
|
4
|
+
export { FXCategoryController } from "./FXCategoryController";
|
|
5
5
|
export * from "./types";
|
package/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.
|
|
20
|
+
exports.FXCategoryController = exports.FXViewController = exports.FXViewManager = exports.FXView = void 0;
|
|
21
21
|
// 主入口文件
|
|
22
22
|
var FXView_1 = require("./FXView");
|
|
23
23
|
Object.defineProperty(exports, "FXView", { enumerable: true, get: function () { return __importDefault(FXView_1).default; } });
|
|
@@ -25,6 +25,6 @@ var FXViewManager_1 = require("./FXViewManager");
|
|
|
25
25
|
Object.defineProperty(exports, "FXViewManager", { enumerable: true, get: function () { return FXViewManager_1.FXViewManager; } });
|
|
26
26
|
var FXViewController_1 = require("./FXViewController");
|
|
27
27
|
Object.defineProperty(exports, "FXViewController", { enumerable: true, get: function () { return FXViewController_1.FXViewController; } });
|
|
28
|
-
var
|
|
29
|
-
Object.defineProperty(exports, "
|
|
28
|
+
var FXCategoryController_1 = require("./FXCategoryController");
|
|
29
|
+
Object.defineProperty(exports, "FXCategoryController", { enumerable: true, get: function () { return FXCategoryController_1.FXCategoryController; } });
|
|
30
30
|
__exportStar(require("./types"), exports);
|
package/index.ts
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
export { default as FXView } from "./FXView";
|
|
3
3
|
export { FXViewManager } from "./FXViewManager";
|
|
4
4
|
export { FXViewController } from "./FXViewController";
|
|
5
|
-
export {
|
|
5
|
+
export { FXCategoryController } from "./FXCategoryController";
|
|
6
6
|
export * from "./types";
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type React from "react";
|
|
|
3
3
|
* 组件控制器接口
|
|
4
4
|
* 用于控制动态组件的显示、隐藏、更新等操作
|
|
5
5
|
*/
|
|
6
|
-
export interface
|
|
6
|
+
export interface FXComponentController {
|
|
7
7
|
/** 显示组件 */
|
|
8
8
|
show: () => void;
|
|
9
9
|
/** 隐藏组件 */
|
|
@@ -28,8 +28,12 @@ export interface ComponentController {
|
|
|
28
28
|
/**
|
|
29
29
|
* 组件项配置接口
|
|
30
30
|
*/
|
|
31
|
-
export interface
|
|
31
|
+
export interface FXComponentItem {
|
|
32
32
|
componentId: string;
|
|
33
33
|
component?: React.ReactNode;
|
|
34
34
|
visible?: boolean;
|
|
35
35
|
}
|
|
36
|
+
export interface FXLifecycleCallbacks {
|
|
37
|
+
didMount: (fxViewId: string) => void;
|
|
38
|
+
willUnmount: (fxViewId: string) => void;
|
|
39
|
+
}
|
package/types.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type React from "react";
|
|
|
6
6
|
* 组件控制器接口
|
|
7
7
|
* 用于控制动态组件的显示、隐藏、更新等操作
|
|
8
8
|
*/
|
|
9
|
-
export interface
|
|
9
|
+
export interface FXComponentController {
|
|
10
10
|
/** 显示组件 */
|
|
11
11
|
show: () => void;
|
|
12
12
|
/** 隐藏组件 */
|
|
@@ -32,8 +32,13 @@ export interface ComponentController {
|
|
|
32
32
|
/**
|
|
33
33
|
* 组件项配置接口
|
|
34
34
|
*/
|
|
35
|
-
export interface
|
|
35
|
+
export interface FXComponentItem {
|
|
36
36
|
componentId: string; // 组件唯一标识(必填)
|
|
37
37
|
component?: React.ReactNode; // 组件内容
|
|
38
38
|
visible?: boolean; // 是否可见,默认为 true
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
export interface FXLifecycleCallbacks {
|
|
42
|
+
didMount: (fxViewId: string) => void;
|
|
43
|
+
willUnmount: (fxViewId: string) => void;
|
|
44
|
+
}
|