最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Element的el-tree控件后臺(tái)數(shù)據(jù)結(jié)構(gòu)的生成以及方法的抽取

 更新時(shí)間:2020年03月05日 11:27:50   作者:java_xxxx  
這篇文章主要介紹了Element的el-tree控件后臺(tái)數(shù)據(jù)結(jié)構(gòu)的生成以及方法的抽取,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

最近用到了el-tree控件,主要是數(shù)據(jù)的格式,按照官網(wǎng)的數(shù)據(jù)格式來(lái)就可以顯示節(jié)點(diǎn)的樹(shù)形結(jié)構(gòu)了。
代碼參考很多

這里給出一個(gè)比較好的鏈接:http://m.fzitv.net/article/181990.htm

代碼說(shuō)明在注釋里寫(xiě)的很詳細(xì)了已經(jīng),這里不再敘述說(shuō)明。至于為什么抽取成這種格式的數(shù)據(jù),那是因?yàn)镋lementUI-tree規(guī)定的數(shù)據(jù)格式,你想要用這個(gè)控件,就必須按照他們規(guī)定的這個(gè)格式 來(lái)。
數(shù)據(jù)格式如下:

Controller代碼

@RequestMapping("/cateList")
  @ResponseBody
  public List<TbCategory> cateList() {

    // 整體思路:
    // 1、取得所有數(shù)據(jù)、放入集合List1 (tbCategories)
    // 2、將List1所有數(shù)據(jù)都放入到map(treeMap)中:元素id為鍵,元素本身對(duì)象為值
    // 3、取得頂層節(jié)點(diǎn)放入集合List2中(resultList)
    // 4、遍歷List1中的所有數(shù)據(jù),通過(guò)數(shù)據(jù)的parentId為鍵在map中取值
    //   1)如果能取到,則說(shuō)明該元素有父節(jié)點(diǎn)
    //      1、判斷該父節(jié)點(diǎn)下的childList中是否有已經(jīng)子節(jié)點(diǎn)
    //       1、若無(wú):則創(chuàng)建一個(gè)集合,將子節(jié)點(diǎn)放入
    //       2、若有:則直接將子節(jié)點(diǎn)放入即可
    // 5、把放好的數(shù)據(jù)放回到map中
    // 6、返回List2(resultList)

    // 注意:整個(gè)過(guò)程將所有數(shù)據(jù)取出放入list2(resultList),返回的也是  //list2


    List<TbCategory> tbCategories = categoryService.cateList();

    List<TbCategory> resultList = new ArrayList<TbCategory>(); // 存貯頂層的數(shù)據(jù)

    Map<Object ,Object> treeMap = new HashMap();
    Object itemTree;

    for(int i = 0;i<tbCategories.size() && !tbCategories.isEmpty();i++){
      itemTree = tbCategories.get(i);
      treeMap.put(tbCategories.get(i).getNodeId(),tbCategories.get(i));// 把所有的數(shù)據(jù)都放到map中


    }


// 這里也可以用另一種方法,就是拿到集合里的每個(gè)元素的父id去數(shù)據(jù)庫(kù)中查詢,但是,這樣與數(shù)據(jù)庫(kù)的交互次數(shù)就太多了
 // 遍歷map得到頂層節(jié)點(diǎn)(游離節(jié)點(diǎn)也算作頂層節(jié)點(diǎn))
    for(int i =0;i<tbCategories.size();i++){
      // 優(yōu)點(diǎn)1:整個(gè)方法,只查詢了一次數(shù)據(jù)庫(kù)
      // 優(yōu)點(diǎn)2:不用知道頂層節(jié)點(diǎn)的id
     if(!treeMap.containsKey(tbCategories.get(i).getParentId())){
        // 我們?cè)诖鎯?chǔ)的時(shí)候就是將元素的id為鍵,元素本身為值存入的
        // 以元素的父id為鍵,在map里取值,若取不到則,對(duì)應(yīng)的元素不存在,即沒(méi)有父節(jié)點(diǎn),為頂層節(jié)點(diǎn)或游離節(jié)點(diǎn)
        // 將頂層節(jié)點(diǎn)放入list集合
        resultList.add(tbCategories.get(i));
      }
    }

    // 循環(huán)數(shù)據(jù),將數(shù)據(jù)放到該節(jié)點(diǎn)的父節(jié)點(diǎn)的children屬性中
    for(int i =0 ;i<tbCategories.size()&& !tbCategories.isEmpty();i++){
      // 數(shù)據(jù)庫(kù)中,若一個(gè)元素有子節(jié)點(diǎn),那么,該元素的id為子節(jié)點(diǎn)的父id
      //treeMap.get(tbCategories.get(i).getParentId()); // 從map集合中找到父節(jié)點(diǎn)
      TbCategory category = (TbCategory)treeMap.get(tbCategories.get(i).getParentId());
      if(category!=null ){ // 不等于null,也就意味著有父節(jié)點(diǎn)
        // 有了父節(jié)點(diǎn),要判斷父節(jié)點(diǎn)下存貯字節(jié)點(diǎn)的集合是否存在,然后將子節(jié)點(diǎn)放入
        if(category.getChildList() == null){
          // 判斷一個(gè)集合是否被創(chuàng)建用null:表示結(jié)合還沒(méi)有被分配內(nèi)存空間(即還沒(méi)有被創(chuàng)建),內(nèi)存大小自然為null
          // 用集合的size判斷集合中是否有元素,為0,沒(méi)有元素(集合已經(jīng)被創(chuàng)建),
          category.setChildList(new ArrayList<TbCategory>());
        }
        category.getChildList().add(tbCategories.get(i)); // 添加到父節(jié)點(diǎn)的ChildList集合下

        // 這一步其實(shí)可以不要,因?yàn)槲覀冃薷牧藬?shù)據(jù)(添加了子節(jié)點(diǎn),然后在將元素放入到map中,
        // 若鍵相同,map會(huì)自動(dòng)覆蓋掉相同的鍵值對(duì),達(dá)到更新map集合中的數(shù)據(jù)的目的),但是我們
        // 這里只是從map中取值,而并不關(guān)心值的子節(jié)點(diǎn)(子節(jié)點(diǎn)是對(duì)象本身自己封裝的。這里我們知道
        // 元素從查詢后放入map,父節(jié)點(diǎn)放入list,然后通過(guò)鍵來(lái)在map中取得對(duì)象,之后再將修改過(guò)的對(duì)象重新放入map當(dāng)中
        // ,我們并沒(méi)有直接操作list,但是在list中對(duì)象的值卻是已經(jīng)修改過(guò)了,這就是對(duì)象的引用傳遞,同一個(gè)引用對(duì)象是通過(guò)
        // 地址值來(lái)操作對(duì)象的,即有不同的引用,但是對(duì)象中的屬性是已經(jīng)通過(guò)引用的操作而改變的,所以這里一旦修改過(guò)后,無(wú)論是map中還是list中,再次取值時(shí)都已經(jīng)是更改過(guò)后的值了)
        treeMap.put(tbCategories.get(i).getParentId(),category); // 把放好的數(shù)據(jù)放回到map中
      }

    }


   return resultList;
  }

實(shí)體類(lèi):

 private Long nodeId;
  private String categoryName;
  private Long parentId;
  private Long childId;
  private List<T> childList;

以上數(shù)據(jù)都在后臺(tái)封裝好了,前臺(tái)直接獲取數(shù)據(jù)顯示即可

<el-tree :data="treeList"
       :props="defaultProps"
       @node-click="handleNodeClick"
       node-key="nodeId"
       show-checkbox=true>
  </el-tree>

js:

defaultProps:{
        children: 'childList',
        label: 'categoryName' // 這里的名字要和你封裝的數(shù)據(jù)中的節(jié)點(diǎn)的名字一樣
      }
// 點(diǎn)擊事件
 handleNodeClick: function (data) {
        console.log("沒(méi)做處理");
      }

方法抽取

上面的方法雖然也能用,但是想把這個(gè)方法抽取成一個(gè)通用的方法,以后再寫(xiě)的時(shí)候就可以直接調(diào)取該方法了。抽取的過(guò)程中還是遇到了很多的問(wèn)題的。

例如實(shí)體類(lèi)A是對(duì)應(yīng)數(shù)據(jù)庫(kù)中存儲(chǔ)節(jié)點(diǎn)的表的實(shí)體類(lèi),但是,實(shí)體類(lèi)中是不存在setChildList、getChildList集合這些方法的。我就把這些存貯信息的字段寫(xiě)在了一個(gè)工具類(lèi)里面,然后方法也在該工具類(lèi)里。這樣返回的時(shí)候就要返回一個(gè)裝有該工具類(lèi)的一個(gè)集合了。還有一個(gè)問(wèn)題就是該工具類(lèi)中都需要那些字段?因?yàn)槭且豢脴?shù),所以我們需要節(jié)點(diǎn)id,幾點(diǎn)的父id,節(jié)點(diǎn)的名稱(chēng),以及存儲(chǔ)子節(jié)點(diǎn)的集合,如果想要更多的數(shù)據(jù),可以添加一個(gè) T data泛型,該泛型直接將原本存儲(chǔ)節(jié)點(diǎn)的實(shí)體類(lèi)對(duì)象存儲(chǔ)進(jìn)來(lái)。這樣所有的數(shù)據(jù)就都整齊了,數(shù)據(jù)結(jié)構(gòu)也就完整了。

contrell代碼:

因?yàn)槲覀兿氤槿∫粋€(gè)公用的方法,那么參數(shù)的類(lèi)型就是不確定的,即傳入的list中元素的類(lèi)型是不固定的,所以要用到泛型。上面說(shuō)過(guò)了,我們要拿到節(jié)點(diǎn)id,父id,以及節(jié)點(diǎn)的名稱(chēng)賦值給工具類(lèi)中對(duì)應(yīng)的字段。但是既然是用泛型,所以就不知道對(duì)象類(lèi)型,所以我們?cè)诠ぞ哳?lèi)中是點(diǎn)不出相應(yīng)的方法來(lái)取到值的,我們就要用到反射,反射的知道類(lèi)中具體的字段或者方法的名字來(lái)取值,所以我們?cè)赾ontroller來(lái)調(diào)用工具類(lèi)的時(shí)候就要,將節(jié)點(diǎn)id、父id和節(jié)點(diǎn)名稱(chēng)傳入。當(dāng)然了還要傳入從后臺(tái)查詢到了裝有數(shù)據(jù)的list集合。

contreller代碼如下所示:

@RequestMapping("/cateList")
@ResponseBody
public List<TreeUtils> cateList() throws Exception{
    List<TbCategory> tbCategories = categoryService.cateList();
    List<TreeUtils> treeList = TreeUtils.getTreeList(tbCategories,"nodeId", "parentId", "categoryName");

    return treeList;
  }

工具類(lèi):

// 抽取方法的時(shí)候要考慮一個(gè)問(wèn)題,即,返回一個(gè)集合,集合中有父節(jié)點(diǎn)和字節(jié)點(diǎn),父節(jié)點(diǎn)和字節(jié)點(diǎn)的類(lèi)型一定要統(tǒng)一,
// 即這里返回的是一個(gè)裝有TreeUtils類(lèi)型的集合,那么集合里的父節(jié)點(diǎn)和子節(jié)點(diǎn)一定都得是TreeUtils類(lèi)型的

public class TreeUtils<T> {

  private Integer id;      // 節(jié)點(diǎn)id
  private Integer parentId;  // 父節(jié)點(diǎn)
  private String name;     // 節(jié)點(diǎn)名稱(chēng) ,返回給前臺(tái)的是一個(gè)裝有TreeUtils的集合的數(shù)據(jù),所以在前臺(tái)顯示數(shù)據(jù)的時(shí)候,el-tree的lable的名字的和這個(gè)一樣
  private List<TreeUtils> childList; // 父節(jié)點(diǎn)中存放子節(jié)點(diǎn)的集合
  private T data;       // 節(jié)點(diǎn)數(shù)據(jù)

方法

/**
   * @param listData  // 從數(shù)據(jù)庫(kù)中查詢的數(shù)據(jù)
   * @return
   */
  public static List<TreeUtils> getTreeList(List<?> listData ,String id,String parentId,String categoryName) throws Exception{

    List<TreeUtils> resultList = new ArrayList<TreeUtils>(); // 最終返回的結(jié)果
    Map<Integer ,Object> map = new HashMap<Integer,Object>();

    for(int i =0;i<listData.size() && !listData.isEmpty();i++){

      // 寫(xiě)一個(gè)與該方法差不多的方法,將得到TreeUtils的代碼抽取出來(lái)
      // 也可以將listData集合整個(gè)轉(zhuǎn)換成裝有TreeUtils的集合x(chóng),然后再循環(huán)x
      TreeUtils treeUtils = new TreeUtils();
      treeUtils.setId(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),id).toString())); // id       // 返回值為Object無(wú)法直接轉(zhuǎn)換成Integer,先toString,再轉(zhuǎn)換成Integer。這里的返回值寫(xiě)成Object是因?yàn)槎喾N類(lèi)型字段的值都可以用該方法
      treeUtils.setParentId(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),parentId).toString())); // 父id
      treeUtils.setName(TreeUtils.getFileValue(listData.get(i),categoryName).toString()); // 節(jié)點(diǎn)名
      //System.out.println("節(jié)點(diǎn)名為+"+TreeUtils.getFileValue(listData.get(i),categoryName).toString());
      treeUtils.setData(listData.get(i));  // data:原對(duì)象中的所有屬性,無(wú)children

      // 通過(guò)反射得到每條數(shù)據(jù)的id將數(shù)據(jù)封裝的map集合中,id為鍵,元素本身為值
      map.put(treeUtils.getId(),treeUtils);


      // 將所有頂層元素添加到resultList集合中
      //if( 0 == treeUtils.getParentId()){
       //  resultList.add(treeUtils);
      // }
    }
// 得到所有的頂層節(jié)點(diǎn),游離節(jié)點(diǎn)也算作頂層節(jié)點(diǎn)
// 優(yōu)點(diǎn)一,不用知道等級(jí)節(jié)點(diǎn)的id
// 優(yōu)點(diǎn)而,只查詢了一次數(shù)據(jù)庫(kù)
    for(int i =0;i<listData.size();i++){
      if(!map.containsKey(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),parentId).toString()))){
        resultList.add((TreeUtils) map.get(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),id).toString())));
      }
    }



    for(int i =0;i<listData.size() && !listData.isEmpty();i++){
      TreeUtils obj = (TreeUtils)map.get(Integer.parseInt(TreeUtils.getFileValue(listData.get(i), parentId).toString()));
      if(obj != null){
        if(obj.getChildList() == null){
          obj.setChildList(new ArrayList());
        }
        obj.getChildList().add(map.get(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),id).toString())));
      }
    }
    return resultList;
  }

反射的方法

/**
   * 通過(guò)反射得到的數(shù)據(jù)類(lèi)型的也是不一定的,所以這里我們返回值為Object
   * Object是無(wú)法直接轉(zhuǎn)為Integer,現(xiàn)將Object轉(zhuǎn)為String,然后再將String轉(zhuǎn)為Integer
   * @param item
   * @param fileName
   * @return
   */
  public static Object getFileValue(Object item,String fileName) throws Exception {
    Class<?> aClass = item.getClass();
    Field file = aClass.getDeclaredField(fileName); // 得到所有字段包括私有字段
    file.setAccessible(true); // 取消訪問(wèn)限制
    return file.get(item);  // 這里就體現(xiàn)出反射的意思了,我們通常都是通過(guò)對(duì)象拿到字段,這里是通過(guò)字段,將類(lèi)的字節(jié)碼對(duì)象為參數(shù)傳入,來(lái)得到值
  }

ps:抽取方法遇到了很多的問(wèn)題,其中的T,?等泛型還只是會(huì)簡(jiǎn)單的用,并不熟練,以后要多加學(xué)習(xí)。

 到此這篇關(guān)于Element的el-tree控件后臺(tái)數(shù)據(jù)結(jié)構(gòu)的生成以及方法的抽取的文章就介紹到這了,更多相關(guān)Element el-tree生成及方法抽取內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue-admin如何實(shí)現(xiàn)動(dòng)態(tài)路由

    vue-admin如何實(shí)現(xiàn)動(dòng)態(tài)路由

    這篇文章主要介紹了vue-admin如何實(shí)現(xiàn)動(dòng)態(tài)路由問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • vue使用prop可以渲染但是打印臺(tái)報(bào)錯(cuò)的解決方式

    vue使用prop可以渲染但是打印臺(tái)報(bào)錯(cuò)的解決方式

    今天小編就為大家分享一篇vue使用prop可以渲染但是打印臺(tái)報(bào)錯(cuò)的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-11-11
  • Vue中$attrs與$listeners的使用教程

    Vue中$attrs與$listeners的使用教程

    這篇文章主要介紹了Vue中$attrs與$listeners的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • vue簡(jiǎn)單練習(xí) 桌面時(shí)鐘的實(shí)現(xiàn)代碼實(shí)例

    vue簡(jiǎn)單練習(xí) 桌面時(shí)鐘的實(shí)現(xiàn)代碼實(shí)例

    這篇文章主要介紹了vue簡(jiǎn)單練習(xí) 桌面時(shí)鐘的實(shí)現(xiàn)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值的相關(guān)資料,需要的朋友可以參考下
    2019-09-09
  • Vue3開(kāi)發(fā)右鍵菜單的示例詳解

    Vue3開(kāi)發(fā)右鍵菜單的示例詳解

    右鍵菜單在項(xiàng)目開(kāi)發(fā)中是屬于比較高頻的組件了,所以這篇文章小編主要來(lái)和大家介紹一下如何利用vue3開(kāi)發(fā)一個(gè)右鍵菜單,有需要的可以參考下
    2024-03-03
  • 詳解VUE中的Proxy代理

    詳解VUE中的Proxy代理

    這篇文章主要介紹了Proxy代理對(duì)象詳解,Proxy 是ES6中提供的一個(gè)非常強(qiáng)大的功能,可以用來(lái)代理另一個(gè)對(duì)象,從而攔截、監(jiān)視并修改這個(gè)對(duì)象的各種操作,需要的朋友可以參考下
    2023-04-04
  • 解決vue js IOS H5focus無(wú)法自動(dòng)彈出鍵盤(pán)的問(wèn)題

    解決vue js IOS H5focus無(wú)法自動(dòng)彈出鍵盤(pán)的問(wèn)題

    今天小編就為大家分享一篇解決vue js IOS H5focus無(wú)法自動(dòng)彈出鍵盤(pán)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • vue中的vendor.js文件過(guò)大問(wèn)題及解決

    vue中的vendor.js文件過(guò)大問(wèn)題及解決

    這篇文章主要介紹了vue中的vendor.js文件過(guò)大問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 配置vue全局方法的兩種方式實(shí)例

    配置vue全局方法的兩種方式實(shí)例

    vue項(xiàng)目中有一些方法需要在多個(gè)頁(yè)面調(diào)用,但為了避免在每個(gè)頁(yè)面都import進(jìn)來(lái),可以把方法加到原型上去,這樣在每個(gè)組件中都能使用了,下面這篇文章主要給大家介紹了關(guān)于配置vue全局方法的兩種方式,需要的朋友可以參考下
    2021-09-09
  • vue實(shí)現(xiàn)在線預(yù)覽pdf文件和下載(pdf.js)

    vue實(shí)現(xiàn)在線預(yù)覽pdf文件和下載(pdf.js)

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)在線預(yù)覽pdf文件和下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11

最新評(píng)論

屏东县| 高淳县| 田阳县| 扎赉特旗| 扎兰屯市| 玉田县| 外汇| 乾安县| 二连浩特市| 台东市| 东城区| 宝清县| 伊金霍洛旗| 墨竹工卡县| 新竹市| 鲁山县| 探索| 榆林市| 黎平县| 江阴市| 厦门市| 城口县| 安国市| 兴隆县| 瑞丽市| 和田市| 东乌| 平顶山市| 临夏市| 德令哈市| 皮山县| 芦山县| 青岛市| 台江县| 巴青县| 阿鲁科尔沁旗| 大同县| 古丈县| 肇东市| 濉溪县| 子长县|