import * as React from 'react'; import { unpack } from '../tools'; /** * pastate 双向数据绑定复选框组件 * 优点: * 1.可以快捷地匿名使用,不用定义新的组件名 * 2.类型提示完善 * 缺点: * 1. 不便于复用 * 2. 不是最优运行效率模式 */ export default class Bind extends React.PureComponent<{ /** 绑定的值 */ value: any /** 组件内部使用的指定显示值的属性名 */ valueProp?: string /** 绑定值改变后进行回调 */ afterChange?: (newValue: any) => void } & Object, any> { onChange = (newValue: any) => { let valueToSet; if(newValue.target){ valueToSet = newValue.target[this.props.valueProp || 'value'] }else{ valueToSet = newValue } let imState = this.props.value if(imState === null || imState === undefined){ throw new Error('[pastate] The binding value cannot be null or undefined. If you want to support null and undefined, you can use store + bind props.') } let store = imState.__store__ if(!store){ throw new Error('[pastate] You can only give state node from this.props to pastate two-ways binding HOC component') } store.set(imState, valueToSet) store.currentActionName = '[binding]' store.sync() this.props.afterChange && this.props.afterChange(valueToSet) } render() { let element: any = this.props.children; if(Array.isArray(element)){ element = element.filter(function(ele: string){ return typeof ele != 'string' }) as any if(element.length == 1){ element = element[0] }else{ throw new Error('[pastate] you can only give only one child to Bind component') } } let component = element.type const { valueProp, afterChange, ...parentProps } = this.props; let props = (Object as any).assign({}, element.props, parentProps, { [this.props.valueProp || 'value']: unpack(this.props.value), onChange: this.onChange, }) return React.createElement( component, props, element.props.children ) } }