ex4nicegui 0.6.9__tar.gz → 0.7.0__tar.gz
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.
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/PKG-INFO +219 -48
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/README.md +217 -46
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/dataSourceFacade.py +20 -20
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/index.py +20 -23
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/EChartsComponent/ECharts.py +9 -8
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/__init__.py +8 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/base.py +61 -54
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/mixins/backgroundColor.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/mixins/disableable.py +8 -8
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/mixins/textColor.py +10 -10
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/aggrid.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/button.py +15 -15
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/checkbox.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/chip.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/circular_progress.py +6 -6
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/color_picker.py +7 -7
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/column.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/date.py +5 -5
- ex4nicegui-0.7.0/ex4nicegui/reactive/officials/dialog.py +49 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/echarts.py +49 -51
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/expansion.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/icon.py +6 -6
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/image.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/input.py +8 -8
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/knob.py +6 -6
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/label.py +6 -6
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/linear_progress.py +6 -6
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/number.py +9 -9
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/radio.py +8 -8
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/row.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/select.py +9 -8
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/slider.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/switch.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/tab.py +0 -12
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/tab_panels.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/table.py +13 -13
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/tabs.py +5 -5
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/textarea.py +5 -5
- ex4nicegui-0.7.0/ex4nicegui/reactive/officials/tooltip.py +40 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/q_pagination.py +5 -5
- ex4nicegui-0.7.0/ex4nicegui/reactive/vfor.js +23 -0
- ex4nicegui-0.7.0/ex4nicegui/reactive/vfor.py +268 -0
- ex4nicegui-0.7.0/ex4nicegui/reactive/view_model.py +160 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/vmodel.py +42 -12
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/signals.py +23 -21
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/pyproject.toml +2 -2
- ex4nicegui-0.6.9/ex4nicegui/reactive/vfor.js +0 -13
- ex4nicegui-0.6.9/ex4nicegui/reactive/vfor.py +0 -198
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/LICENSE +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/dataSource.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/containers.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/layouts.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/models.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/text.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/ui_aggrid.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/ui_date_picker.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/ui_date_picker.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/ui_echarts.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/ui_radio.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/ui_range.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/ui_select.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/ui_slider.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/elements/ui_table.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/protocols.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/bi/types.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/experimental_/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/experimental_/gridLayout/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/experimental_/gridLayout/index.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/gsap/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/gsap/gsap.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/gsap/timeline.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/gsap/timeline.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/gsap/wrapGsap.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/helper/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/helper/client_instance_locker.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/layout/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/layout/gridFlex/GridFlex.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/layout/gridFlex/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/layout/gridFlex/gridFlex.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/layout/gridFlex/utils.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/layout/rxFlex/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/layout/rxFlex/index.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/layout/rxFlex/types.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/d3/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/d3/d3-color.ems.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/d3/d3-dispatch.ems.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/d3/d3-drag.ems.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/d3/d3-ease.ems.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/d3/d3-interpolate.ems.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/d3/d3-selection.ems.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/d3/d3-timer.ems.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/d3/d3-transition.ems.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/d3/d3-zoom.ems.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/.DS_Store +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/CSSPlugin.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/CSSRulePlugin.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/CustomEase.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/Draggable.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/EasePack.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/EaselPlugin.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/Flip.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/MotionPathPlugin.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/Observer.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/PixiPlugin.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/ScrollToPlugin.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/ScrollTrigger.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/TextPlugin.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/all.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/gsap-core.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/gsap.mjs +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/utils/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/utils/matrix.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/utils/paths.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/libs/gsap/utils/strings.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/EChartsComponent/ECharts.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/EChartsComponent/events.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/EChartsComponent/types.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/EChartsComponent/utils.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/UseDraggable/UseDraggable.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/UseDraggable/UseDraggable.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/deferredTask.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/dropZone/dropZone.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/dropZone/dropZone.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/empty.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/empty.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/fileWatcher.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/local_file_picker.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/mermaid/mermaid.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/mermaid/mermaid.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/base.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/card.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/drawer.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/element.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/grid.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/html.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/html.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/tab_panel.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/officials/upload.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/rxui.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/scopedStyle.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/scopedStyle.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/services/pandas_service.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/services/reactive_service.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/systems/color_system.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/systems/object_system.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/systems/reactive_system.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/transitionGroup.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/transitionGroup.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/useMouse/UseMouse.js +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/useMouse/UseMouse.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/reactive/usePagination.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/tools/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/tools/debug.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/__init__.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/apiEffect.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/asyncComputed.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/clientScope.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/common.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/effect.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/refComputed.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/refWrapper.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/scheduler.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/utils/types.py +0 -0
- {ex4nicegui-0.6.9 → ex4nicegui-0.7.0}/ex4nicegui/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ex4nicegui
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Extension library based on nicegui, providing data responsive,BI functionality modules
|
|
5
5
|
Home-page: https://github.com/CrystalWindSnake/ex4nicegui
|
|
6
6
|
License: MIT
|
|
@@ -17,13 +17,17 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
18
|
Requires-Dist: executing (>=2.0.1,<3.0.0)
|
|
19
19
|
Requires-Dist: nicegui (>=1.4.25,<2.0.0)
|
|
20
|
-
Requires-Dist: signe (>=0.4.
|
|
20
|
+
Requires-Dist: signe (>=0.4.20,<0.5.0)
|
|
21
21
|
Project-URL: Repository, https://github.com/CrystalWindSnake/ex4nicegui
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
|
|
24
24
|
# ex4nicegui
|
|
25
|
-
[ENGLISH README](./README.en.md)
|
|
26
25
|
|
|
26
|
+
<div align="center">
|
|
27
|
+
|
|
28
|
+
简体中文| [English](./README.en.md)
|
|
29
|
+
|
|
30
|
+
</div>
|
|
27
31
|
|
|
28
32
|
- [教程](#教程)
|
|
29
33
|
- [安装](#-安装)
|
|
@@ -191,6 +195,154 @@ ui.run()
|
|
|
191
195
|
---
|
|
192
196
|
|
|
193
197
|
|
|
198
|
+
|
|
199
|
+
## ViewModel
|
|
200
|
+
在 `v0.7.0` 版本中,引入 `ViewModel` 类,用于管理一组响应式数据。
|
|
201
|
+
|
|
202
|
+
下面是一个简单的计算器示例:
|
|
203
|
+
|
|
204
|
+
1. 当用户修改数值输入框或符号选择框,右侧会自动显示计算结果
|
|
205
|
+
2. 当结果小于 0 时,结果显示为红色,否则为黑色
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
from ex4nicegui import rxui
|
|
209
|
+
|
|
210
|
+
class Calculator(rxui.ViewModel):
|
|
211
|
+
num1 = rxui.var(0)
|
|
212
|
+
sign = rxui.var("+")
|
|
213
|
+
num2 = rxui.var(0)
|
|
214
|
+
|
|
215
|
+
def result(self):
|
|
216
|
+
# 当 num1,sign,num2 任意一个值发生变化时,result 也会重新计算
|
|
217
|
+
return eval(f"{self.num1.value}{self.sign.value}{self.num2.value}")
|
|
218
|
+
|
|
219
|
+
# 每个对象拥有独立的数据
|
|
220
|
+
calc = Calculator()
|
|
221
|
+
|
|
222
|
+
with ui.row(align_items="center"):
|
|
223
|
+
rxui.number(value=calc.num1, label="Number 1")
|
|
224
|
+
rxui.select(value=calc.sign, options=["+", "-", "*", "/"], label="Sign")
|
|
225
|
+
rxui.number(value=calc.num2, label="Number 2")
|
|
226
|
+
ui.label("=")
|
|
227
|
+
rxui.label(calc.result).bind_color(
|
|
228
|
+
lambda: "red" if calc.result() < 0 else "black"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### cached_var
|
|
234
|
+
|
|
235
|
+
上面的示例中,由于使用了两次 `calc.result` 。因此,每当 `num1`, `sign`, `num2` 任意一个值发生变化时,`result` 都会执行2次。
|
|
236
|
+
|
|
237
|
+
实际上,第二次的计算是多余的。我们可以通过添加 `rxui.cached_var` 装饰器,避免多余的计算。
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
class Calculator(rxui.ViewModel):
|
|
241
|
+
...
|
|
242
|
+
|
|
243
|
+
@rxui.cached_var
|
|
244
|
+
def result(self):
|
|
245
|
+
return eval(f"{self.num1.value}{self.sign.value}{self.num2.value}")
|
|
246
|
+
|
|
247
|
+
...
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### 使用列表
|
|
253
|
+
|
|
254
|
+
当数据为可变对象时,比如列表,字典等,需要提供工厂函数传给 `rxui.var`
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
class Home(rxui.ViewModel):
|
|
259
|
+
persons= rxui.var(lambda: [])
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
下面的示例,每个 person 使用卡片展示。最上方显示所有人的平均年龄。当个人年龄大于平均年龄,卡片外边框将变为红色。
|
|
264
|
+
通过 `number` 组件修改年龄,一切都会自动更新。
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
from ex4nicegui import rxui, Ref
|
|
268
|
+
from itertools import count
|
|
269
|
+
|
|
270
|
+
id_generator = count()
|
|
271
|
+
|
|
272
|
+
class Person(rxui.ViewModel):
|
|
273
|
+
name = rxui.var("")
|
|
274
|
+
age = rxui.var(0)
|
|
275
|
+
|
|
276
|
+
def __init__(self, name: str = "", age: int = 0):
|
|
277
|
+
super().__init__()
|
|
278
|
+
self.name.value = name
|
|
279
|
+
self.age.value = age
|
|
280
|
+
self.id = next(id_generator)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
class Home(rxui.ViewModel):
|
|
284
|
+
persons: Ref[List[Person]] = rxui.var(lambda: [])
|
|
285
|
+
|
|
286
|
+
def avg_age(self) -> float:
|
|
287
|
+
if len(self.persons.value) == 0:
|
|
288
|
+
return 0
|
|
289
|
+
|
|
290
|
+
return sum(p.age.value for p in self.persons.value) / len(self.persons.value)
|
|
291
|
+
|
|
292
|
+
def sample_data(self):
|
|
293
|
+
self.persons.value = [
|
|
294
|
+
Person("alice", 25),
|
|
295
|
+
Person("bob", 30),
|
|
296
|
+
Person("charlie", 31),
|
|
297
|
+
Person("dave", 22),
|
|
298
|
+
Person("eve", 26),
|
|
299
|
+
Person("frank", 29),
|
|
300
|
+
]
|
|
301
|
+
|
|
302
|
+
home = Home()
|
|
303
|
+
home.sample_data()
|
|
304
|
+
|
|
305
|
+
rxui.label(lambda: f"平均年龄: {home.avg_age()}")
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
with ui.row():
|
|
309
|
+
|
|
310
|
+
@rxui.vfor(home.persons, key="id")
|
|
311
|
+
def _(store: rxui.VforStore[Person]):
|
|
312
|
+
person = store.get_item()
|
|
313
|
+
with rxui.card().classes("outline").bind_classes(
|
|
314
|
+
{
|
|
315
|
+
"outline-red-500": lambda: person.age.value > home.avg_age(),
|
|
316
|
+
}
|
|
317
|
+
):
|
|
318
|
+
rxui.input(value=person.name, placeholder="名字")
|
|
319
|
+
rxui.number(value=person.age, min=1, max=100, step=1, placeholder="年龄")
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
如果你觉得 `rxui.vfor` 代码过于复杂,可以使用 `effect_refreshable` 装饰器代替。
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
from ex4nicegui import rxui, Ref,effect_refreshable
|
|
327
|
+
...
|
|
328
|
+
|
|
329
|
+
# 明确指定监控 home.persons 变化,可以避免意味刷新
|
|
330
|
+
@effect_refreshable.on(home.persons)
|
|
331
|
+
def _():
|
|
332
|
+
|
|
333
|
+
for person in home.persons.value:
|
|
334
|
+
...
|
|
335
|
+
rxui.number(value=person.age, min=1, max=100, step=1, placeholder="年龄")
|
|
336
|
+
...
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
需要注意到,每当 `home.persons` 列表变化时(比如新增或删除元素),`effect_refreshable` 装饰的函数都会重新执行。意味着所有元素都会重新创建。
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
更多复杂的应用,可以查看 [examples](./examples)
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
194
346
|
## 响应式
|
|
195
347
|
|
|
196
348
|
```python
|
|
@@ -331,15 +483,14 @@ ui.button("change", on_click=change_value)
|
|
|
331
483
|
|
|
332
484
|
> `ref_computed` 是只读的 `to_ref`
|
|
333
485
|
|
|
334
|
-
|
|
335
|
-
如果你更喜欢通过类组织代码,`ref_computed` 同样支持作用到实例方法上
|
|
486
|
+
从 `v0.7.0` 版本开始,不建议使用 `ref_computed` 应用实例方法。你可以使用 `rxui.ViewModel`,并使用 `rxui.cached_var` 装饰器
|
|
336
487
|
|
|
337
488
|
```python
|
|
338
|
-
class MyState:
|
|
489
|
+
class MyState(rxui.ViewModel):
|
|
339
490
|
def __init__(self) -> None:
|
|
340
491
|
self.r_text = to_ref("")
|
|
341
492
|
|
|
342
|
-
@
|
|
493
|
+
@rxui.cached_var
|
|
343
494
|
def post_text(self):
|
|
344
495
|
return self.r_text.value + "post"
|
|
345
496
|
|
|
@@ -494,70 +645,90 @@ rxui.input(value=data.value["a"])
|
|
|
494
645
|
rxui.input(value=lambda: data.value["a"])
|
|
495
646
|
|
|
496
647
|
# 要使用 vmodel 才能双向绑定
|
|
497
|
-
rxui.input(value=rxui.vmodel(data
|
|
648
|
+
rxui.input(value=rxui.vmodel(data, "a"))
|
|
649
|
+
|
|
650
|
+
# 也可以直接使用,但不推荐
|
|
651
|
+
rxui.input(value=rxui.vmodel(data.value['a']))
|
|
652
|
+
|
|
498
653
|
```
|
|
499
654
|
|
|
500
|
-
-
|
|
655
|
+
- 第一个输入框将完全失去响应性,因为代码等价于 `rxui.input(value=1)`
|
|
501
656
|
- 第二个输入框由于使用函数,将得到读取响应性(第三个输入框输入值,将得到同步)
|
|
502
657
|
- 第三个输入框,使用 `rxui.vmodel` 包裹,即可实现双向绑定
|
|
503
658
|
|
|
504
|
-
|
|
659
|
+
> 如果使用 `rxui.ViewModel` ,你可能不需要使用 `vmodel`
|
|
505
660
|
|
|
661
|
+
可参考 [todo list 案例](./examples/todomvc/)
|
|
662
|
+
|
|
663
|
+
---
|
|
506
664
|
|
|
507
665
|
### vfor
|
|
508
|
-
|
|
666
|
+
基于列表响应式数据,渲染列表组件。每项组件按需更新。数据项支持字典或任意类型对象。
|
|
667
|
+
|
|
668
|
+
从 `v0.7.0` 版本开始,建议配合 `rxui.ViewModel` 使用。与使用 `effect_refreshable` 装饰器不同,`vfor` 不会重新创建所有的元素,而是更新已存在的元素。
|
|
669
|
+
|
|
670
|
+
下面是卡片排序例子,卡片总是按年龄排序。当你修改某个卡片中的年龄数据时,卡片会实时调整顺序。但是,光标焦点不会离开输入框。
|
|
671
|
+
|
|
509
672
|
|
|
510
673
|
```python
|
|
674
|
+
from typing import List
|
|
511
675
|
from nicegui import ui
|
|
512
|
-
from ex4nicegui
|
|
513
|
-
from ex4nicegui import deep_ref, ref_computed
|
|
514
|
-
from typing import Dict
|
|
515
|
-
|
|
516
|
-
# refs
|
|
517
|
-
items = deep_ref(
|
|
518
|
-
[
|
|
519
|
-
{"id": 1, "message": "foo", "done": False},
|
|
520
|
-
{"id": 2, "message": "bar", "done": True},
|
|
521
|
-
]
|
|
522
|
-
)
|
|
676
|
+
from ex4nicegui import rxui, deep_ref as ref, Ref
|
|
523
677
|
|
|
524
|
-
# ref_computeds
|
|
525
|
-
@ref_computed
|
|
526
|
-
def done_count_info():
|
|
527
|
-
return f"done count:{sum(item['done'] for item in items.value)}"
|
|
528
678
|
|
|
529
|
-
|
|
530
|
-
def
|
|
531
|
-
|
|
532
|
-
|
|
679
|
+
class Person(rxui.ViewModel):
|
|
680
|
+
def __init__(self, name: str, age: int) -> None:
|
|
681
|
+
self.name = name
|
|
682
|
+
self.age = ref(age)
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
class MyApp(rxui.ViewModel):
|
|
686
|
+
persons: Ref[List[Person]] = rxui.var(lambda: [])
|
|
687
|
+
order = rxui.var("asc")
|
|
688
|
+
|
|
689
|
+
def sort_by_age(self):
|
|
690
|
+
return sorted(
|
|
691
|
+
self.persons.value,
|
|
692
|
+
key=lambda p: p.age.value,
|
|
693
|
+
reverse=self.order.value == "desc",
|
|
694
|
+
)
|
|
695
|
+
|
|
696
|
+
@staticmethod
|
|
697
|
+
def create():
|
|
698
|
+
persons = [
|
|
699
|
+
Person(name="Alice", age=25),
|
|
700
|
+
Person(name="Bob", age=30),
|
|
701
|
+
Person(name="Charlie", age=20),
|
|
702
|
+
Person(name="Dave", age=35),
|
|
703
|
+
Person(name="Eve", age=28),
|
|
704
|
+
]
|
|
705
|
+
app = MyApp()
|
|
706
|
+
app.persons.value = persons
|
|
707
|
+
return app
|
|
533
708
|
|
|
534
709
|
|
|
535
710
|
# ui
|
|
536
|
-
|
|
537
|
-
ui.button("check", on_click=check)
|
|
711
|
+
app = MyApp.create()
|
|
538
712
|
|
|
713
|
+
with rxui.tabs(app.order):
|
|
714
|
+
rxui.tab("asc", "Ascending")
|
|
715
|
+
rxui.tab("desc", "Descending")
|
|
539
716
|
|
|
540
|
-
@rxui.vfor(items,key='id')
|
|
541
|
-
def _(store: rxui.VforStore[Dict]):
|
|
542
|
-
# 函数中构建每一行数据的界面
|
|
543
|
-
item = store.get() # 通过 store.get 获取对应行的响应式对象(相当于每行的数据 to_ref(...))
|
|
544
|
-
mes = rxui.vmodel(item.value['message']) # 复杂结构默认没有双向绑定,需要使用 `vmodel`
|
|
545
717
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
rxui.
|
|
718
|
+
@rxui.vfor(app.sort_by_age, key="name")
|
|
719
|
+
def each_person(s: rxui.VforStore[Person]):
|
|
720
|
+
person = s.get_item()
|
|
721
|
+
|
|
722
|
+
with ui.card(), ui.row(align_items="center"):
|
|
723
|
+
rxui.label(person.name)
|
|
724
|
+
rxui.number(value=person.age, step=1, min=0, max=100)
|
|
552
725
|
|
|
553
726
|
```
|
|
554
727
|
|
|
555
728
|
- `rxui.vfor` 装饰器到自定义函数
|
|
556
|
-
-
|
|
557
|
-
- 第二个参数 `key`: 为了可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你可以为每个元素对应的块提供一个唯一的 key
|
|
558
|
-
- 自定义函数带有一个参数。通过 `store.
|
|
559
|
-
|
|
560
|
-
> vfor 渲染的项目,只有在新增数据时,才会创建
|
|
729
|
+
- 第一个参数传入响应式列表。注意,无须调用 `app.sort_by_age`
|
|
730
|
+
- 第二个参数 `key`: 为了可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你可以为每个元素对应的块提供一个唯一的 key 。默认情况使用列表元素索引。例子中假定每个人的名字唯一。
|
|
731
|
+
- 自定义函数带有一个参数。通过 `store.get_item` 可以获取当前行的对象。由于 Person 本身继承自 `rxui.ViewModel`,所以它的各项属性可以直接绑定到组件。
|
|
561
732
|
|
|
562
733
|
|
|
563
734
|
---
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# ex4nicegui
|
|
2
|
-
[ENGLISH README](./README.en.md)
|
|
3
2
|
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
简体中文| [English](./README.en.md)
|
|
6
|
+
|
|
7
|
+
</div>
|
|
4
8
|
|
|
5
9
|
- [教程](#教程)
|
|
6
10
|
- [安装](#-安装)
|
|
@@ -168,6 +172,154 @@ ui.run()
|
|
|
168
172
|
---
|
|
169
173
|
|
|
170
174
|
|
|
175
|
+
|
|
176
|
+
## ViewModel
|
|
177
|
+
在 `v0.7.0` 版本中,引入 `ViewModel` 类,用于管理一组响应式数据。
|
|
178
|
+
|
|
179
|
+
下面是一个简单的计算器示例:
|
|
180
|
+
|
|
181
|
+
1. 当用户修改数值输入框或符号选择框,右侧会自动显示计算结果
|
|
182
|
+
2. 当结果小于 0 时,结果显示为红色,否则为黑色
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from ex4nicegui import rxui
|
|
186
|
+
|
|
187
|
+
class Calculator(rxui.ViewModel):
|
|
188
|
+
num1 = rxui.var(0)
|
|
189
|
+
sign = rxui.var("+")
|
|
190
|
+
num2 = rxui.var(0)
|
|
191
|
+
|
|
192
|
+
def result(self):
|
|
193
|
+
# 当 num1,sign,num2 任意一个值发生变化时,result 也会重新计算
|
|
194
|
+
return eval(f"{self.num1.value}{self.sign.value}{self.num2.value}")
|
|
195
|
+
|
|
196
|
+
# 每个对象拥有独立的数据
|
|
197
|
+
calc = Calculator()
|
|
198
|
+
|
|
199
|
+
with ui.row(align_items="center"):
|
|
200
|
+
rxui.number(value=calc.num1, label="Number 1")
|
|
201
|
+
rxui.select(value=calc.sign, options=["+", "-", "*", "/"], label="Sign")
|
|
202
|
+
rxui.number(value=calc.num2, label="Number 2")
|
|
203
|
+
ui.label("=")
|
|
204
|
+
rxui.label(calc.result).bind_color(
|
|
205
|
+
lambda: "red" if calc.result() < 0 else "black"
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### cached_var
|
|
211
|
+
|
|
212
|
+
上面的示例中,由于使用了两次 `calc.result` 。因此,每当 `num1`, `sign`, `num2` 任意一个值发生变化时,`result` 都会执行2次。
|
|
213
|
+
|
|
214
|
+
实际上,第二次的计算是多余的。我们可以通过添加 `rxui.cached_var` 装饰器,避免多余的计算。
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
class Calculator(rxui.ViewModel):
|
|
218
|
+
...
|
|
219
|
+
|
|
220
|
+
@rxui.cached_var
|
|
221
|
+
def result(self):
|
|
222
|
+
return eval(f"{self.num1.value}{self.sign.value}{self.num2.value}")
|
|
223
|
+
|
|
224
|
+
...
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
### 使用列表
|
|
230
|
+
|
|
231
|
+
当数据为可变对象时,比如列表,字典等,需要提供工厂函数传给 `rxui.var`
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
class Home(rxui.ViewModel):
|
|
236
|
+
persons= rxui.var(lambda: [])
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
下面的示例,每个 person 使用卡片展示。最上方显示所有人的平均年龄。当个人年龄大于平均年龄,卡片外边框将变为红色。
|
|
241
|
+
通过 `number` 组件修改年龄,一切都会自动更新。
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
from ex4nicegui import rxui, Ref
|
|
245
|
+
from itertools import count
|
|
246
|
+
|
|
247
|
+
id_generator = count()
|
|
248
|
+
|
|
249
|
+
class Person(rxui.ViewModel):
|
|
250
|
+
name = rxui.var("")
|
|
251
|
+
age = rxui.var(0)
|
|
252
|
+
|
|
253
|
+
def __init__(self, name: str = "", age: int = 0):
|
|
254
|
+
super().__init__()
|
|
255
|
+
self.name.value = name
|
|
256
|
+
self.age.value = age
|
|
257
|
+
self.id = next(id_generator)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class Home(rxui.ViewModel):
|
|
261
|
+
persons: Ref[List[Person]] = rxui.var(lambda: [])
|
|
262
|
+
|
|
263
|
+
def avg_age(self) -> float:
|
|
264
|
+
if len(self.persons.value) == 0:
|
|
265
|
+
return 0
|
|
266
|
+
|
|
267
|
+
return sum(p.age.value for p in self.persons.value) / len(self.persons.value)
|
|
268
|
+
|
|
269
|
+
def sample_data(self):
|
|
270
|
+
self.persons.value = [
|
|
271
|
+
Person("alice", 25),
|
|
272
|
+
Person("bob", 30),
|
|
273
|
+
Person("charlie", 31),
|
|
274
|
+
Person("dave", 22),
|
|
275
|
+
Person("eve", 26),
|
|
276
|
+
Person("frank", 29),
|
|
277
|
+
]
|
|
278
|
+
|
|
279
|
+
home = Home()
|
|
280
|
+
home.sample_data()
|
|
281
|
+
|
|
282
|
+
rxui.label(lambda: f"平均年龄: {home.avg_age()}")
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
with ui.row():
|
|
286
|
+
|
|
287
|
+
@rxui.vfor(home.persons, key="id")
|
|
288
|
+
def _(store: rxui.VforStore[Person]):
|
|
289
|
+
person = store.get_item()
|
|
290
|
+
with rxui.card().classes("outline").bind_classes(
|
|
291
|
+
{
|
|
292
|
+
"outline-red-500": lambda: person.age.value > home.avg_age(),
|
|
293
|
+
}
|
|
294
|
+
):
|
|
295
|
+
rxui.input(value=person.name, placeholder="名字")
|
|
296
|
+
rxui.number(value=person.age, min=1, max=100, step=1, placeholder="年龄")
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
如果你觉得 `rxui.vfor` 代码过于复杂,可以使用 `effect_refreshable` 装饰器代替。
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
from ex4nicegui import rxui, Ref,effect_refreshable
|
|
304
|
+
...
|
|
305
|
+
|
|
306
|
+
# 明确指定监控 home.persons 变化,可以避免意味刷新
|
|
307
|
+
@effect_refreshable.on(home.persons)
|
|
308
|
+
def _():
|
|
309
|
+
|
|
310
|
+
for person in home.persons.value:
|
|
311
|
+
...
|
|
312
|
+
rxui.number(value=person.age, min=1, max=100, step=1, placeholder="年龄")
|
|
313
|
+
...
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
需要注意到,每当 `home.persons` 列表变化时(比如新增或删除元素),`effect_refreshable` 装饰的函数都会重新执行。意味着所有元素都会重新创建。
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
更多复杂的应用,可以查看 [examples](./examples)
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
171
323
|
## 响应式
|
|
172
324
|
|
|
173
325
|
```python
|
|
@@ -308,15 +460,14 @@ ui.button("change", on_click=change_value)
|
|
|
308
460
|
|
|
309
461
|
> `ref_computed` 是只读的 `to_ref`
|
|
310
462
|
|
|
311
|
-
|
|
312
|
-
如果你更喜欢通过类组织代码,`ref_computed` 同样支持作用到实例方法上
|
|
463
|
+
从 `v0.7.0` 版本开始,不建议使用 `ref_computed` 应用实例方法。你可以使用 `rxui.ViewModel`,并使用 `rxui.cached_var` 装饰器
|
|
313
464
|
|
|
314
465
|
```python
|
|
315
|
-
class MyState:
|
|
466
|
+
class MyState(rxui.ViewModel):
|
|
316
467
|
def __init__(self) -> None:
|
|
317
468
|
self.r_text = to_ref("")
|
|
318
469
|
|
|
319
|
-
@
|
|
470
|
+
@rxui.cached_var
|
|
320
471
|
def post_text(self):
|
|
321
472
|
return self.r_text.value + "post"
|
|
322
473
|
|
|
@@ -471,70 +622,90 @@ rxui.input(value=data.value["a"])
|
|
|
471
622
|
rxui.input(value=lambda: data.value["a"])
|
|
472
623
|
|
|
473
624
|
# 要使用 vmodel 才能双向绑定
|
|
474
|
-
rxui.input(value=rxui.vmodel(data
|
|
625
|
+
rxui.input(value=rxui.vmodel(data, "a"))
|
|
626
|
+
|
|
627
|
+
# 也可以直接使用,但不推荐
|
|
628
|
+
rxui.input(value=rxui.vmodel(data.value['a']))
|
|
629
|
+
|
|
475
630
|
```
|
|
476
631
|
|
|
477
|
-
-
|
|
632
|
+
- 第一个输入框将完全失去响应性,因为代码等价于 `rxui.input(value=1)`
|
|
478
633
|
- 第二个输入框由于使用函数,将得到读取响应性(第三个输入框输入值,将得到同步)
|
|
479
634
|
- 第三个输入框,使用 `rxui.vmodel` 包裹,即可实现双向绑定
|
|
480
635
|
|
|
481
|
-
|
|
636
|
+
> 如果使用 `rxui.ViewModel` ,你可能不需要使用 `vmodel`
|
|
482
637
|
|
|
638
|
+
可参考 [todo list 案例](./examples/todomvc/)
|
|
639
|
+
|
|
640
|
+
---
|
|
483
641
|
|
|
484
642
|
### vfor
|
|
485
|
-
|
|
643
|
+
基于列表响应式数据,渲染列表组件。每项组件按需更新。数据项支持字典或任意类型对象。
|
|
644
|
+
|
|
645
|
+
从 `v0.7.0` 版本开始,建议配合 `rxui.ViewModel` 使用。与使用 `effect_refreshable` 装饰器不同,`vfor` 不会重新创建所有的元素,而是更新已存在的元素。
|
|
646
|
+
|
|
647
|
+
下面是卡片排序例子,卡片总是按年龄排序。当你修改某个卡片中的年龄数据时,卡片会实时调整顺序。但是,光标焦点不会离开输入框。
|
|
648
|
+
|
|
486
649
|
|
|
487
650
|
```python
|
|
651
|
+
from typing import List
|
|
488
652
|
from nicegui import ui
|
|
489
|
-
from ex4nicegui
|
|
490
|
-
from ex4nicegui import deep_ref, ref_computed
|
|
491
|
-
from typing import Dict
|
|
492
|
-
|
|
493
|
-
# refs
|
|
494
|
-
items = deep_ref(
|
|
495
|
-
[
|
|
496
|
-
{"id": 1, "message": "foo", "done": False},
|
|
497
|
-
{"id": 2, "message": "bar", "done": True},
|
|
498
|
-
]
|
|
499
|
-
)
|
|
653
|
+
from ex4nicegui import rxui, deep_ref as ref, Ref
|
|
500
654
|
|
|
501
|
-
# ref_computeds
|
|
502
|
-
@ref_computed
|
|
503
|
-
def done_count_info():
|
|
504
|
-
return f"done count:{sum(item['done'] for item in items.value)}"
|
|
505
655
|
|
|
506
|
-
|
|
507
|
-
def
|
|
508
|
-
|
|
509
|
-
|
|
656
|
+
class Person(rxui.ViewModel):
|
|
657
|
+
def __init__(self, name: str, age: int) -> None:
|
|
658
|
+
self.name = name
|
|
659
|
+
self.age = ref(age)
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
class MyApp(rxui.ViewModel):
|
|
663
|
+
persons: Ref[List[Person]] = rxui.var(lambda: [])
|
|
664
|
+
order = rxui.var("asc")
|
|
665
|
+
|
|
666
|
+
def sort_by_age(self):
|
|
667
|
+
return sorted(
|
|
668
|
+
self.persons.value,
|
|
669
|
+
key=lambda p: p.age.value,
|
|
670
|
+
reverse=self.order.value == "desc",
|
|
671
|
+
)
|
|
672
|
+
|
|
673
|
+
@staticmethod
|
|
674
|
+
def create():
|
|
675
|
+
persons = [
|
|
676
|
+
Person(name="Alice", age=25),
|
|
677
|
+
Person(name="Bob", age=30),
|
|
678
|
+
Person(name="Charlie", age=20),
|
|
679
|
+
Person(name="Dave", age=35),
|
|
680
|
+
Person(name="Eve", age=28),
|
|
681
|
+
]
|
|
682
|
+
app = MyApp()
|
|
683
|
+
app.persons.value = persons
|
|
684
|
+
return app
|
|
510
685
|
|
|
511
686
|
|
|
512
687
|
# ui
|
|
513
|
-
|
|
514
|
-
ui.button("check", on_click=check)
|
|
688
|
+
app = MyApp.create()
|
|
515
689
|
|
|
690
|
+
with rxui.tabs(app.order):
|
|
691
|
+
rxui.tab("asc", "Ascending")
|
|
692
|
+
rxui.tab("desc", "Descending")
|
|
516
693
|
|
|
517
|
-
@rxui.vfor(items,key='id')
|
|
518
|
-
def _(store: rxui.VforStore[Dict]):
|
|
519
|
-
# 函数中构建每一行数据的界面
|
|
520
|
-
item = store.get() # 通过 store.get 获取对应行的响应式对象(相当于每行的数据 to_ref(...))
|
|
521
|
-
mes = rxui.vmodel(item.value['message']) # 复杂结构默认没有双向绑定,需要使用 `vmodel`
|
|
522
694
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
rxui.
|
|
695
|
+
@rxui.vfor(app.sort_by_age, key="name")
|
|
696
|
+
def each_person(s: rxui.VforStore[Person]):
|
|
697
|
+
person = s.get_item()
|
|
698
|
+
|
|
699
|
+
with ui.card(), ui.row(align_items="center"):
|
|
700
|
+
rxui.label(person.name)
|
|
701
|
+
rxui.number(value=person.age, step=1, min=0, max=100)
|
|
529
702
|
|
|
530
703
|
```
|
|
531
704
|
|
|
532
705
|
- `rxui.vfor` 装饰器到自定义函数
|
|
533
|
-
-
|
|
534
|
-
- 第二个参数 `key`: 为了可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你可以为每个元素对应的块提供一个唯一的 key
|
|
535
|
-
- 自定义函数带有一个参数。通过 `store.
|
|
536
|
-
|
|
537
|
-
> vfor 渲染的项目,只有在新增数据时,才会创建
|
|
706
|
+
- 第一个参数传入响应式列表。注意,无须调用 `app.sort_by_age`
|
|
707
|
+
- 第二个参数 `key`: 为了可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你可以为每个元素对应的块提供一个唯一的 key 。默认情况使用列表元素索引。例子中假定每个人的名字唯一。
|
|
708
|
+
- 自定义函数带有一个参数。通过 `store.get_item` 可以获取当前行的对象。由于 Person 本身继承自 `rxui.ViewModel`,所以它的各项属性可以直接绑定到组件。
|
|
538
709
|
|
|
539
710
|
|
|
540
711
|
---
|
|
@@ -228,26 +228,26 @@ class DataSourceFacade(Generic[_TData]):
|
|
|
228
228
|
|
|
229
229
|
Support pyecharts
|
|
230
230
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
231
|
+
.. code-block:: python
|
|
232
|
+
import pandas as pd
|
|
233
|
+
from ex4nicegui import bi
|
|
234
|
+
from pyecharts.charts import Bar
|
|
235
|
+
|
|
236
|
+
df = pd.DataFrame({"name": list("abcdc"), "value": range(5)})
|
|
237
|
+
ds = bi.data_source(df)
|
|
238
|
+
|
|
239
|
+
@ds.ui_echarts
|
|
240
|
+
def bar(data: pd.DataFrame):
|
|
241
|
+
c = (
|
|
242
|
+
Bar()
|
|
243
|
+
.add_xaxis(data["name"].tolist())
|
|
244
|
+
.add_yaxis("value", data["value"].tolist())
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
return c
|
|
248
|
+
|
|
249
|
+
bar.classes("h-[20rem]")
|
|
250
|
+
|
|
251
251
|
|
|
252
252
|
"""
|
|
253
253
|
return ui_echarts(self, fn)
|