欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

clojurescript-- TreeSelect树形结构多选

程序员文章站 2022-06-08 16:31:01
...

最近项目遇到一个树形结构数据的多选操作,
上页面直观感受一下:如下图就是我想要的结果
clojurescript-- TreeSelect树形结构多选
根据上图,知道自己要干的事什么事情了吧。先思考几个问题?

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] [])))

现在,树形结构的多选就完成了