123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- import classNames from './classNames'
- import eventsMixin from './eventsMixin'
- const DEFAULT_TRIGGER = 'onClick'
- const CELL_NAME = '../cell/index'
- const FIELD_NAME = '../field/index'
- const defaultToolbar = {
- title: '请选择',
- cancelText: '取消',
- confirmText: '确定',
- }
- const defaultEvents = {
- onChange() {},
- onConfirm() {},
- onCancel() {},
- onVisibleChange() {},
- onValueChange() {},
- }
- const defaultPlatformProps = {
- labelPropName: 'label',
- format(values, props) {
- return Array.isArray(values.displayValue) ? values.displayValue.join(',') : values.displayValue
- },
- }
- const defaultFieldNames = {
- label: 'label',
- value: 'value',
- children: 'children',
- }
- export default function popupMixin(selector = '#wux-picker', platformProps = defaultPlatformProps) {
- return Behavior({
- behaviors: [eventsMixin({ defaultEvents })],
- properties: {
- toolbar: {
- type: Object,
- value: defaultToolbar,
- },
- trigger: {
- type: String,
- value: DEFAULT_TRIGGER,
- },
- defaultVisible: {
- type: Boolean,
- value: false,
- },
- visible: {
- type: Boolean,
- value: false,
- },
- controlled: {
- type: Boolean,
- value: false,
- },
- disabled: {
- type: Boolean,
- value: false,
- },
- },
- data: {
- mounted: false,
- popupVisible: false,
- inputValue: [],
- },
- methods: {
- /**
- * 设置组件显示或隐藏
- */
- setVisibleState(popupVisible, callback = () => {}) {
- if (this.data.popupVisible !== popupVisible) {
- const params = {
- mounted: true,
- inputValue: this.data.value, // forceUpdate
- popupVisible,
- }
- this.setData(popupVisible ? params : { popupVisible }, () => {
- // collect field component & forceUpdate
- if (popupVisible && this.hasFieldDecorator) {
- const field = this.getFieldElem()
- if (field) {
- field.changeValue(field.data.value)
- }
- }
- callback()
- })
- }
- },
- /**
- * 触发 visibleChange 事件
- */
- fireVisibleChange(popupVisible) {
- if (this.data.popupVisible !== popupVisible) {
- if (!this.data.controlled) {
- this.setVisibleState(popupVisible)
- }
- this.setScrollValue(undefined)
- this.triggerEvent('visibleChange', { visible: popupVisible })
- }
- },
- /**
- * 打开
- */
- open() {
- this.fireVisibleChange(true)
- },
- /**
- * 关闭
- */
- close(callback) {
- if (typeof callback === 'function') {
- const values = this.getPickerValue(this.scrollValue || this.data.inputValue)
- callback.call(this, this.formatPickerValue(values))
- }
- this.fireVisibleChange(false)
- },
- /**
- * 组件关闭时重置其内部数据
- */
- onClosed() {
- this.picker = null
- this.setData({ mounted: false, inputValue: null })
- },
- /**
- * 点击确定按钮时的回调函数
- */
- onConfirm() {
- this.close((values) => {
- this.triggerEvent('change', values) // collect field component
- this.triggerEvent('confirm', values)
- })
- },
- /**
- * 点击取消按钮时的回调函数
- */
- onCancel() {
- this.close((values) => this.triggerEvent('cancel', values))
- },
- /**
- * 每列数据选择变化后的回调函数
- */
- onValueChange(e) {
- if (!this.data.mounted) return
- const { value } = e.detail
- if (this.data.cascade) {
- this.setCasecadeScrollValue(value)
- } else {
- this.setScrollValue(value)
- }
- this.updated(value, true)
- this.triggerEvent('valueChange', this.formatPickerValue(e.detail))
- },
- /**
- * 获取当前 picker 的值
- */
- getPickerValue(value = this.data.inputValue) {
- this.picker = this.picker || this.selectComponent(selector)
- return this.picker && this.picker.getValue(value)
- },
- /**
- * 格式化 picker 返回值
- */
- formatPickerValue(values) {
- return {
- ...values,
- [platformProps.labelPropName]: platformProps.format(values, this.data),
- }
- },
- /**
- * 获取 field 父元素
- */
- getFieldElem() {
- return this.field = (this.field || this.getRelationNodes(FIELD_NAME)[0])
- },
- /**
- * 设置子元素 props
- */
- setChildProps() {
- if (this.data.disabled) return
- const elements = this.getRelationNodes(CELL_NAME)
- const { trigger = DEFAULT_TRIGGER } = this.data
- if (elements.length > 0) {
- elements.forEach((inputElem) => {
- const { inputEvents } = inputElem.data
- const oriInputEvents = inputElem.data.oriInputEvents || { ...inputEvents }
- inputEvents[trigger] = (...args) => {
- if (oriInputEvents && oriInputEvents[trigger]) {
- oriInputEvents[trigger](...args)
- }
- this.onTriggerClick()
- }
- inputElem.setData({ oriInputEvents, inputEvents })
- })
- }
- },
- /**
- * 触发事件
- */
- onTriggerClick() {
- this.fireVisibleChange(!this.data.popupVisible)
- },
- /**
- * 阻止移动触摸
- */
- noop() {},
- /**
- * 更新值
- */
- updated(inputValue, isForce) {
- if (!this.hasFieldDecorator || isForce) {
- if (this.data.inputValue !== inputValue) {
- this.setData({ inputValue })
- }
- }
- },
- /**
- * 记录每列数据的变化值
- */
- setScrollValue(value) {
- this.scrollValue = value
- },
- /**
- * 记录每列数据的变化值 - 针对于级联
- */
- setCasecadeScrollValue(value) {
- if (value && this.scrollValue) {
- const length = this.scrollValue.length
- if (length === value.length && this.scrollValue[length - 1] === value[length - 1]) {
- return
- }
- }
- this.setScrollValue(value)
- },
- },
- lifetimes: {
- ready() {
- const { defaultVisible, visible, controlled, value } = this.data
- const popupVisible = controlled ? visible : defaultVisible
- // 若 defaultFieldNames 存在,则缓存之,并传递给子组件,只生效一次
- if ('defaultFieldNames' in this.data) {
- this.setData({
- fieldNames: Object.assign({}, defaultFieldNames, this.data.defaultFieldNames),
- })
- }
- this.mounted = true
- this.scrollValue = undefined
- this.setVisibleState(popupVisible)
- this.setChildProps()
- },
- detached() {
- this.mounted = false
- },
- },
- definitionFilter(defFields) {
- // set default child
- Object.assign(defFields.relations = (defFields.relations || {}), {
- [CELL_NAME]: {
- type: 'child',
- observer() {
- this.setChildProps()
- },
- },
- [FIELD_NAME]: {
- type: 'ancestor',
- },
- })
- // set default classes
- Object.assign(defFields.computed = (defFields.computed || {}), {
- classes: ['prefixCls', function(prefixCls) {
- const wrap = classNames(prefixCls)
- const toolbar = `${prefixCls}__toolbar`
- const inner = `${prefixCls}__inner`
- const cancel = classNames(`${prefixCls}__button`, {
- [`${prefixCls}__button--cancel`]: true,
- })
- const confirm = classNames(`${prefixCls}__button`, {
- [`${prefixCls}__button--confirm`]: true,
- })
- const hover = `${prefixCls}__button--hover`
- const title = `${prefixCls}__title`
- return {
- wrap,
- toolbar,
- inner,
- cancel,
- confirm,
- hover,
- title,
- }
- }],
- })
- // set default observers
- Object.assign(defFields.observers = (defFields.observers || {}), {
- visible(popupVisible) {
- if (this.data.controlled) {
- this.setVisibleState(popupVisible)
- }
- },
- value(value) {
- this.updated(value)
- },
- })
- },
- })
- }
|