useConditionDataManager.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import {toValue, ref, watch, computed} from 'vue'
  2. import _ from "lodash";
  3. import {empty} from "@/uni_modules/uv-ui-tools/libs/function/test";
  4. import {useConditionFactory} from "@/components/mx-condition/useConditionFactory";
  5. export const useConditionDataManager = function (configs, eventManager, queryParams, sharedData, console) {
  6. const container = ref(new Map())
  7. const rules = ref({})
  8. watch(queryParams, async () => {
  9. console.log('dataManager begin init', new Date().getTime())
  10. const keys = Object.keys(queryParams.value)
  11. if (!keys.length) return
  12. const keysConfig = configs.map(c => c.key)
  13. const missingKeys = _.difference(keys, keysConfig)
  14. if (missingKeys.length) console.warn('missing keys: ' + missingKeys.toString())
  15. // 没有被依赖的属性需要在改变时触发查询
  16. // 依赖是在config中指定的,但是否没有被依赖需要遍历所有条件才能知道
  17. const keysNotBeDependent = [...keys]
  18. keys.forEach(key => {
  19. const config = configs.find(c => c.key == key)
  20. if (!config) return _.pull(keysNotBeDependent, key)
  21. _.pull(keysNotBeDependent, ...config.dependentKeys)
  22. const condition = useConditionFactory(config, eventManager, queryParams, sharedData, console)
  23. container.value.set(key, condition)
  24. // useConditionFactory可能会对规则进行加工
  25. if (!empty(config.rule)) rules.value[config.key] = config.rule
  26. // 必须条件立马加入workingList,防止事件过早触发
  27. if (condition.config.required) eventManager.push('dataManager init of required', key)
  28. })
  29. // 一般来说必须得有1个非被依赖项,才能构成一个响应链,否则没有机会触发onSearch
  30. // TODO:这里只是当1个警告,实际运行效果还待评估
  31. if (!keysNotBeDependent.length) console.warn('At least one key must not be dependent!')
  32. keysNotBeDependent.forEach(k => {
  33. watch(() => toValue(queryParams)[k], () => eventManager.trigger('dataManager watch not be dependent of ' + k))
  34. })
  35. }, {immediate: true})
  36. const conditions = computed(() => [...container.value.values()])
  37. const filterConditions = computed(() => conditions.value.filter(c => !c.config.hidden))
  38. const needValidation = computed(() => !empty(rules.value))
  39. const reset = function () {
  40. container.value.clear()
  41. rules.value = {}
  42. }
  43. return {
  44. container,
  45. conditions: filterConditions,
  46. rules,
  47. needValidation,
  48. reset
  49. }
  50. }