Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangfisher committed Jan 8, 2024
1 parent 32f4f29 commit 04d7ea9
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 88 deletions.
8 changes: 3 additions & 5 deletions example/src/FormDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const NetworkForm = ()=>{
</FieldRow>
}}
</Network.Field>
<Network.Field<typeof Network.fields.ip> name="ip">
{/* <Network.Field<typeof Network.fields.ip> name="ip">
{({title,value,visible,validate,placeholder,sync})=>{
return <FieldRow visible={visible} label={title}>
<input className={classnames({invalid:!validate.value})} placeholder={placeholder} value={value} onChange={sync(100)}/>
Expand Down Expand Up @@ -160,7 +160,7 @@ const NetworkForm = ()=>{
<input className={classnames({invalid:!validate})} value={value} onChange={sync()}/>
</FieldRow>
}}
</Network.Field>
</Network.Field> */}
</Card>
</Network.Form>
}
Expand All @@ -170,9 +170,7 @@ const NetworkForm = ()=>{
const FormDemo:React.FC = ()=>{
// 如果缺少以下两句,则state.select无法触发setOnReadHook
const [state] = Network.store.useState()
useEffect(()=>{
JSON.stringify(state.interface.select)
})


// state.dhcp.start.validate.value

Expand Down
109 changes: 53 additions & 56 deletions example/src/forms/network.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ const formSchema ={
value:"React-Helux-Form",
placeholder:"输入网络配置名称",
title:"网络名称",
validate:(value:string)=>value.length>3,
validate1:computed((value:string)=>value.length>3,{}),
validate2:computed(async (value:string)=>value.length>3,[]),
validate3:computed(async (value:string)=>value.length>3,[],{})
validate:(value:string)=>value.length>3
},
interface:{
value:"wifi",
Expand All @@ -23,58 +20,58 @@ const formSchema ={
return [{value:"wifi",title:"无线网卡"},{value:"ethernet",title:"有线网卡"}]
}
},
ip:{
value:"1.1.1.1",
title:"IP地址",
validate:async ([value]:any)=>{
await delay(2000)
return validator.isIP(value)
}
},
gateway:{
value:"1.1.1.1",
title:"网关地址",
validate:(value:any)=>validator.isIP(value)
},
dhcp:{
enable:{
title:"自动获取IP地址",
value:true
},
start:{
title:"起始地址",
value:"192.168.1.1",
visible:computed<boolean>((dhcp:any)=>{
return dhcp.enable.value
},{context:ComputedScopeRef.Parent}),
validate:(value:any)=>validator.isIP(value)
},
end:{
title:"结束地址",
value:"192.168.1.100",
// 将visible的context指向父对象即dhcp
visible:computed<boolean>((state:any)=>{
return state.dhcp.enable.value
},{context:ComputedScopeRef.Root}),
validate:(value:any)=>validator.isIP(value)
}
},
wifi:{
title:"无线配置",
visible:(net:any)=>(net as NetworkType).interface.value==="wifi",
ssid:{
value:"fast",
placeholder:"无线网络",
validate:(value:string)=>value.length>3
},
password:{
value:"123",
placeholder:"输入无线密码",
help:"密码长度应不小于6位",
enable:(net:any)=>(net as NetworkType).interface.value==="wifi",
validate:(value:string)=>value.length>6
}
},
// ip:{
// value:"1.1.1.1",
// title:"IP地址",
// validate:async (value:any)=>{
// await delay(2000)
// return validator.isIP(value)
// }
// },
// gateway:{
// value:"1.1.1.1",
// title:"网关地址",
// validate:(value:any)=>validator.isIP(value)
// },
// dhcp:{
// enable:{
// title:"自动获取IP地址",
// value:true
// },
// start:{
// title:"起始地址",
// value:"192.168.1.1",
// visible:computed<boolean>((dhcp:any)=>{
// return dhcp.enable.value
// },{context:ComputedScopeRef.Parent}),
// validate:(value:any)=>validator.isIP(value)
// },
// end:{
// title:"结束地址",
// value:"192.168.1.100",
// // 将visible的context指向父对象即dhcp
// visible:computed<boolean>((state:any)=>{
// return state.dhcp.enable.value
// },{context:ComputedScopeRef.Root}),
// validate:(value:any)=>validator.isIP(value)
// }
// },
// wifi:{
// title:"无线配置",
// visible:(net:any)=>(net as NetworkType).interface.value==="wifi",
// ssid:{
// value:"fast",
// placeholder:"无线网络",
// validate:(value:string)=>value.length>3
// },
// password:{
// value:"123",
// placeholder:"输入无线密码",
// help:"密码长度应不小于6位",
// enable:(net:any)=>(net as NetworkType).interface.value==="wifi",
// validate:(value:string)=>value.length>6
// }
// },
// dns:[],
// subnetMask:"",
// mac:"",
Expand Down
4 changes: 2 additions & 2 deletions packages/form/src/action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ import { getVal } from "@helux/utils";
import React from "react";
import { defaultObject } from "flex-tools/object/defaultObject";
import type { FormOptions } from "./form";
import { AsyncComputedObject, AsyncComputedReturns, ComputedParams, ComputedScopeRef, computed } from "helux-store";
import { AsyncComputedObject, ComputedAsyncReturns, ComputedParams, ComputedScopeRef, computed } from "helux-store";
import { assignObject } from "flex-tools/object/assignObject";
import type { ChangeFieldType } from "flex-tools/types";


export type ActionComputedAttr<R=unknown,Fields=any> = ((fields:Fields)=>R)
| ((fields:Fields)=>Promise<R>)
| AsyncComputedReturns<R>
| ComputedAsyncReturns<R>
| R


Expand Down
6 changes: 4 additions & 2 deletions packages/form/src/field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export function createFieldComponent(this:Required<FormOptions>,store: any) {
const fieldPath = Array.isArray(name) ? name : name.split(".")
// 含fields前缀的字段路径
const fullFieldPath:string[] = ['fields',...fieldPath]
const valueFieldPath:string[] = ['fields',...fieldPath]

const [state,setState] = store.useState()

Expand All @@ -132,13 +133,14 @@ export function createFieldComponent(this:Required<FormOptions>,store: any) {
const isLite = isLiteField(value)
if(!isLite) {
fieldPath.push("value")
valueFieldPath.push("value")
}

// 更新当前字段信息,如update(field=>field.enable=true)
const filedUpdater = useFieldUpdater(store,fullFieldPath,setState)
const filedUpdater = useFieldUpdater(store,valueFieldPath,setState)

// 表单字段同步,允许指定防抖参数
const syncer = useFieldSyncer(store,fullFieldPath)
const syncer = useFieldSyncer(store,valueFieldPath)

const [fieldProps,setFieldProps] = useState(()=>createFieldProps(self.getFieldName(fieldPath),value,syncer,filedUpdater))

Expand Down
15 changes: 4 additions & 11 deletions packages/form/src/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
*/

import React, { useCallback } from "react";
import { type StoreDefine, createStore,RequiredComputedState, ComputedScopeRef, ComputedOptions, AsyncComputedReturns, AsyncComputedObject } from "helux-store";
import { type StoreDefine, createStore,RequiredComputedState, ComputedScopeRef, ComputedOptions } from "helux-store";
import type { ReactFC, Dict, ComputedAttr } from "./types";
import { FieldComponent, createFieldComponent } from "./field";
import { FieldGroupComponent, createFieldGroupComponent } from "./fieldGroup";
Expand Down Expand Up @@ -137,23 +137,16 @@ export interface FormState<Fields extends Dict = Dict,Actions extends Dict = Dic
* 经过处理后
*
* 如果validator是由computed函数创建的,由于computed函数可以指定依赖和计算上下文,有较强的自由度,因此不做任何处理
* 仅当validator是一个普通的同步函数和异步函数时,才进行处理
* 仅当validator不是由computed函数创建时
*
* 处理方式:
* - 同步计算函数的context指向当前字段值
* - 异步函数的第一个依赖指向当前字段的值value
*
*/
function createValidatorHook(keyPath:string[],getter:Function,options:ComputedOptions){
if(options.async){ // 异步计算函数
// 异步计算的输入参数是([depends],ctx),如果异步计算函数不是使用computed声明的,没有指定依赖,则自动将对对段值value作为第一个依赖
const deps = options.depends || []
if(Array.isArray(deps)) deps.splice(0,0,[...keyPath.slice(0,keyPath.length-1),'value'])
options.depends = deps
}else{//同步计算函数
//同步计算函数将从默认的根状态对象更改为当前字段的值
options.context = 'value' // == 上下文总是指向当前字段的值
}
// 如果没有指定scope,则默认指向value
if(options.scope==undefined) options.scope="value"
options.initial = true // 初始化true
}

Expand Down
4 changes: 2 additions & 2 deletions packages/form/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { AsyncComputedObject, AsyncComputedReturns, ComputedState,PickComputedReturns,RequiredComputedState } from "helux-store";
import { AsyncComputedObject,ComputedAsyncReturns } from "helux-store";


// 用来声明表单定义中的动态计算属性
export type ComputedAttr<R=unknown,Args extends any[]=any[]> = ((...args:Args)=>R)
| ((...args:Args)=>Promise<R>)
| AsyncComputedObject<R>
| AsyncComputedReturns<R>
| ComputedAsyncReturns<R>
| R


Expand Down
20 changes: 10 additions & 10 deletions packages/store/src/computed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { ComputedScopeRef } from './store';
import { getVal, setVal } from "@helux/utils";
import { isAsyncFunction } from "flex-tools/typecheck/isAsyncFunction";
import { isPlainObject } from "flex-tools/typecheck/isPlainObject";
import { skipComputed,isSkipComputed } from "./utils"
import { skipComputed,isSkipComputed, getValue } from "./utils"

export interface ComputedParams extends Record<string,any>{
// 获取一个进度条,用来显示异步计算的进度
Expand Down Expand Up @@ -81,22 +81,20 @@ function getComputedContextDraft(draft:any,{context,keyPath,fullKeyPath,depends}
const ctx = typeof(context)=='function' ? context(draft) : context

if(ctx === ComputedScopeRef.Current){
return keyPath.length==0 ? draft : getVal(draft, keyPath)
}else if(ctx === ComputedScopeRef.Parent){
const paths = fullKeyPath.slice(0,fullKeyPath.length-2)
return paths.length > 0 ? getVal(draft,paths) : draft
return getValue(draft, keyPath)
}else if(ctx === ComputedScopeRef.Parent){
return getValue(draft,fullKeyPath.slice(0,fullKeyPath.length-2))
}else if(ctx === ComputedScopeRef.Root){
return draft
}else if(ctx === ComputedScopeRef.Depends){ // 异步计算的依赖值
return Array.isArray(depends) ? depends : []
}else if(typeof(ctx)=='string'){ // 当前对象的指定键
return getVal(draft,[...keyPath,...ctx.split(".")])
return getValue(draft,[...keyPath,...ctx.split(".")])
}else if(Array.isArray(ctx)){
return ctx.length > 0 ? getVal(draft,ctx) : draft
return getValue(draft,ctx)
}else if(typeof(ctx)=='number'){
const endIndex = ctx > fullKeyPath.length-2 ? fullKeyPath.length-ctx-1 : 0
const paths = fullKeyPath.slice(0,endIndex)
return paths.length>0 ? getVal(draft,paths) : draft
return getValue(draft,fullKeyPath.slice(0,endIndex))
}else{
return draft
}
Expand Down Expand Up @@ -144,7 +142,9 @@ export function computed<R=any>(getter:any,depends:any,options?: ComputedOptions
},arguments[2] || {})
}else{
opts.depends = [] // 同步计算函数不需要指定依赖
Object.assign(opts,arguments[1] || {})
Object.assign(opts,{
scope:ComputedScopeRef.Current, // 异步计算函数的上下文指向依赖
},arguments[1] || {})
}

opts.async = isAsync
Expand Down

0 comments on commit 04d7ea9

Please sign in to comment.