clojurescript-- TreeSelect树形结构多选
程序员文章站
2022-06-08 16:31:01
...
最近项目遇到一个树形结构数据的多选操作,
上页面直观感受一下:如下图就是我想要的结果
根据上图,知道自己要干的事什么事情了吧。先思考几个问题?
1.怎么获取数据?数据格式是什么样子
;;treeselect数据格式
[{" title":"","value":"","children":[{"title":"","value":"","children":[{}]}]}]
2.页面怎么画?
3.多选应该怎么选?
第一步:获取要页面要渲染的数据
涉及到xx_event.cljs、xxx_sub.cljs、url.cljs几个文件
xxx_event.cljs:
(ns custom-manage.fabric.fabric-events
(:require
["antd" :as ant]
[kee-frame.core :as kf]
[clojure.string :as string]
[custom-manage.url :refer [fabric-url]]))
;;触发调获取品类接口
+ (kf/reg-chain
+ :fabric/get-fabric-categories
+ (fn [{:keys [db]}]
+ {:dispatch [:request/get {:url (:categories fabric-url)
+ :callback-event :fabric/categories-success}]}))
;;当接口有返回值则把数据保存到db里
+ (kf/reg-event-fx
+ :fabric/categories-success
+ (fn [{:keys [db]} [data]]
+ {:db (assoc-in db [:fabric :fabric-categories]
+ ;;把数据做个处理,转化为treeselect的格式,这样页面才能显示
+ (make-category-tree data))}))
这里需要说明一下make-category-tree
这个方法,是需要把数据中的key改为为 treeselcet中treeData能识别的key(title、value、children)
treedata:
[ {
title: 'Node1',
value: '0-0',
key: '0-0',
children: [
{
title: 'Child Node1',
value: '0-0-0',
key: '0-0-0',
},
],
},
{
title: 'Child Node5',
value: '0-1-2',
key: '0-1-2',
}]
url.cljs里面存放的是接口url
(ns custom-manage.url
(:require [custom-manage.config :refer [domain]]))
;;面料
(def fabric-url
{:list (str domain "/admin/fabric/list")
+ :categories (str domain "/admin/category/second/tree")})
现在为止数据已经可以获取到,然后存放到db中了
第二步:画页面,渲染树形结构数据
xxx_form_views.cljs
(ns custom-manage.fabric.fabric-form-views
(:require
["antd" :as ant]
[reagent.core :as r]
[re-frame.core :as rf]
[custom-manage.common.utils :as utils]
[custom-manage.fabric.fabric-events]
[custom-manage.components.upload :refer [file-upload]]
[custom-manage.components.common-page :refer [main-page]]
[custom-manage.fabric.fabric-form-component :as component]))
(def FormItem (.-Item ant/Form))
(def TextArea (.-TextArea ant/Input))
(defn fabric-form-page []
(def fabric-detail (rf/subscribe [:fabric-sub/fabric-form]))
(fn []
(utils/create-form
(fn [props]
[main-page {:title (if (:fabric_id @fabric-detail) "更新面料" "添加面料")
:on-back #(rf/dispatch [:core/nav :main {:path "/base-data/fabric-list"}])}
(let [form (utils/get-form)
set-fields-value (:setFieldsValue form)]
[:> ant/Form
[:> FormItem {:label "名称:"
:labelCol {:span 6}
:wrapperCol {:span 10}}
(utils/decorate-field
form "fabric_name"
{:initialValue (:fabric_name @fabric-detail)
:rules [{:required true :message "请输入名称"}]}
[:> ant/Input {:placeholder "请输入名称"}])]
[:> FormItem {:label "编码:"
:labelCol {:span 6}
:wrapperCol {:span 10}}
(utils/decorate-field
form "fabric_code"
{:initialValue (:fabric_code @fabric-detail)
:rules [{:required true :message "请输入编码"}]}
[:> ant/Input {:placeholder "请输入编码"}])]
[:> FormItem {:label "价格:"
:labelCol {:span 6}
:wrapperCol {:span 10}}
(utils/decorate-field
form "fabric_price"
{:initialValue (:fabric_price @fabric-detail)
:rules [{:required true :message "请输入价格"}]}
[:> ant/InputNumber {:placeholder "请输入价格" :style {:width "100%"} :min 0}])]
[:> FormItem {:label "上架:"
:labelCol {:span 6}
:wrapperCol {:span 10}}
(utils/decorate-field
form "shelf_flag"
{:initialValue (if (= "1" (:shelf_flag @fabric-detail)) true false)
:valuePropName "checked"
:rules [{:required true}]}
[:> ant/Switch {:checkedChildren "是"
:unCheckedChildren "否"}])]
[:> FormItem {:label "图片:"
:labelCol {:span 6}
:wrapperCol {:span 10}}
(utils/decorate-field
form "fabric_url"
{:initialValue (:fabric_url @fabric-detail)
:rules [{:required true :message "请上传图片"}]}
[file-upload
{:files (:logo-img @fabric-detail)
:data {:file_prefix "fabric"}
:on-change (fn [{:keys [file]}]
(if (not= (:status file) "removed")
(if-let [url (get-in file [:response :data :file_url])]
(set-fields-value (clj->js {:fabric_url url}))
(set-fields-value (clj->js {:fabric_url ""})))
(set-fields-value (clj->js {:fabric_url ""})))
(rf/dispatch [:fabric/set-logo-img file]))}])]
+ (let [select-data (rf/subscribe [:fabric_sub/fabric-categories])
+ select-loading (rf/subscribe [:fabric_sub/categroy-loading])
+ selected-values (rf/subscribe [:fabric_sub/category-values])]
+ [:div
+ [component/category-select-item
+ {:title "关联品类"
+ :searchPlaceholder "请选择品类"
+ :allow-clear true
+ :select-data @select-data
+ :select-values @selected-values
+ :select-loading @select-loading
+ :on-select-change #(rf/dispatch [:fabric/set-detail-categories %])}]])
[:> FormItem {:wrapperCol {:offset 10}}
[:> ant/Button
{:type "primary"
:on-click
(fn []
((:validateFieldsAndScroll form)
(fn [err values]
(prn values)
(when (not err)
(rf/dispatch [:fabric/submit-fabric
(into {}
(remove (fn [[k v]] (nil? v)) (js->clj values :keywordize-keys true)))])))))} "提交"]]])]))))
因为项目需要,我把categroy品类这一模块单独拿出来了,只做选择,可以直接就放在FortItem里,不用单独拿出来。
fabric-form-cpmponent.cljs:
(ns custom-manage.fabric.fabric-form-component
(:require ["antd" :as ant]
["uuid" :as uid]
[reagent.core :as r]
[re-frame.core :as rf]))
(defn category-select [{:keys [title placeholder allow-clear
select-data select-values select-loading
on-select-change on-select on-deselect]}]
[:> ant/Row
[:> ant/Col {:span 24}
[:> FormItem {:label title
:labelCol {:span 6}
:wrapperCol {:span 10 #_18}}
[:> ant/TreeSelect
(merge
{:treeData select-data
:treeCheckable true
:value (or select-values [])
:searchPlaceholder "请选择品类"}
(when on-select-change
{:onChange (fn [value]
(on-select-change (js->clj value :keywordize-keys true)))})
(when on-select
{:onSelect (fn [value label extra] (on-select (:ref (js->clj value :keywordize-keys true))))})
)]]]])
(defn category-select-item [props]
[:div
[category-select props]
[:> ant/Row
[:> ant/Col {:span 12 :offset 6}
[category-list props]]]])
第三步:选择操作
把选择的选项保存到db里
xxx_event.cljs
+ (kf/reg-event-db
+ :fabric/set-detail-categories
+ (assoc-in db [:fabric :detail :categories] data))
xxx_sub.cljs
+ (rf/reg-sub
+ :fabric_sub/fabric-categories+
+ (fn [db]
+ (get-in db [:fabric :fabric-categories] [])))
+ (rf/reg-sub
+ :fabric_sub/category-values
+ (fn [db]
+ (get-in db [:fabric :detail :categories] [])))
现在,树形结构的多选就完成了
上一篇: 是时候放弃Masonry了