乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      ExtJS 4 樹(shù) – ExtJS4中文教程 | Show Framework

       旭龍 2013-01-22

      ExtJS 4 樹(shù) – ExtJS4中文教程

      ExtJS 4 樹(shù)

      Tree Panel是ExtJS中最多能的組件之一,它非常適合用于展示分層的數(shù)據(jù)。Tree PanelGrid Panel繼承自相同的基類,所以所有從Grid Panel能獲得到的特性、擴(kuò)展、插件等帶來(lái)的好處,在Tree Panel中也同樣可以獲得。列、列寬調(diào)整、拖拽、渲染器、排序、過(guò)濾等特性,在兩種組件中都是差不多的工作方式。

      讓我們開(kāi)始創(chuàng)建一個(gè)簡(jiǎn)單的樹(shù)組件

      Ext.create('Ext.tree.Panel', {
          renderTo: Ext.getBody(),
          title: 'Simple Tree',
          width: 150,
          height: 150,
          root: {
              text: 'Root',
              expanded: true,
              children: [
                  {
                      text: 'Child 1',
                      leaf: true
                  },
                  {
                      text: 'Child 2',
                      leaf: true
                  },
                  {
                      text: 'Child 3',
                      expanded: true,
                      children: [
                          {
                              text: 'Grandchild',
                              leaf: true
                          }
                      ]
                  }
              ]
          }
      });
      

      運(yùn)行效果如圖

      extjs-4-tree-smiple-tree.png

      這個(gè)Tree Panel直接渲染在document.body上,我們定義了一個(gè)默認(rèn)展開(kāi)的根節(jié)點(diǎn),根節(jié)點(diǎn)有三個(gè)子節(jié)點(diǎn),前兩個(gè)子節(jié)點(diǎn)是葉子節(jié)點(diǎn),這意味著他們不能擁有自己的子節(jié)點(diǎn)了,第三個(gè)節(jié)點(diǎn)不是葉子節(jié)點(diǎn),它有一個(gè)子節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)的text屬性用來(lái)設(shè)置節(jié)點(diǎn)上展示的文字。

      Tree Panel內(nèi)部使用Tree Store存儲(chǔ)數(shù)據(jù)。上面的例子中使用了root配置項(xiàng)作為使用store的捷徑。如果我們單獨(dú)指定store,代碼像這樣:

      var store = Ext.create('Ext.data.TreeStore', {
          root: {
              text: 'Root',
              expanded: true,
              children: [
                  {
                      text: 'Child 1',
                      leaf: true
                  },
                  {
                      text: 'Child 2',
                      leaf: true
                  },
                  ...
              ]
          }
      });
      
      Ext.create('Ext.tree.Panel', {
          title: 'Simple Tree',
          store: store,
          ...
      });
      

      The Node Interface 節(jié)點(diǎn)接口

      上面的例子中我們?cè)诠?jié)點(diǎn)上設(shè)定了兩三個(gè)不同的屬性,但是節(jié)點(diǎn)到底是什么?前面提到,TreePanel綁定了一個(gè)TreeStore,Store在ExtJS中的作用是管理Model實(shí)例的集合。樹(shù)節(jié)點(diǎn)是用NodeInterface裝飾的簡(jiǎn)單的模型實(shí)例。用NodeInterface裝飾Model使Model獲得了在樹(shù)中使用需要的方法、屬性、字段。下面是個(gè)樹(shù)節(jié)點(diǎn)對(duì)象在開(kāi)發(fā)工具中打印的截圖

      extjs-4-tree-node-interface.png

      關(guān)于節(jié)點(diǎn)的方法、屬性等,請(qǐng)查看API文檔(ps. 每一個(gè)學(xué)習(xí)ExtJS的開(kāi)發(fā)者都應(yīng)該仔細(xì)研讀API文檔,這是最好的教材)

      Visually changing your tree 外觀定制

      先嘗試一些簡(jiǎn)單的改動(dòng)。把useArrows設(shè)置為true,Tree Panel就會(huì)隱藏前導(dǎo)線使用箭頭表示節(jié)點(diǎn)的展開(kāi)

      extjs-4-trees-arrows.png

      設(shè)置rootVisible屬性為false,根節(jié)點(diǎn)就會(huì)被隱藏起來(lái):

      extjs-4-trees-root-lines.png

      Multiple columns 多列

      由于Tree Panel也是從Grid Panel相同的父類繼承的,因此實(shí)現(xiàn)多列很容易。

      var tree = Ext.create('Ext.tree.Panel', {
          renderTo: Ext.getBody(),
          title: 'TreeGrid',
          width: 300,
          height: 150,
          fields: ['name', 'description'], //注意這里
          columns: [{
              xtype: 'treecolumn',
              text: 'Name',
              dataIndex: 'name',
              width: 150,
              sortable: true
          }, {
              text: 'Description',
              dataIndex: 'description',
              flex: 1,
              sortable: true
          }],
          root: {
              name: 'Root',
              description: 'Root description',
              expanded: true,
              children: [{
                  name: 'Child 1',
                  description: 'Description 1',
                  leaf: true
              }, {
                  name: 'Child 2',
                  description: 'Description 2',
                  leaf: true
              }]
          }
      });
      

      extjs-4-trees-multiple-columns.png

      這里面的columns配置項(xiàng)期望得到一個(gè)Ext.grid.column.Column配置,就跟GridPanel一樣的。唯一的不同就是Tree Panel需要至少一個(gè)treecolumn列,這種列是擁有tree視覺(jué)效果的,典型的Tree Panel應(yīng)該只有一列treecolumn。

      fields配置項(xiàng)會(huì)傳遞給tree內(nèi)置生成的store用。dataIndex是如何跟列匹配的請(qǐng)仔細(xì)看上面例子中的 namedescription,其實(shí)就是和每個(gè)節(jié)點(diǎn)附帶的屬性值匹配

      如果不配置column,tree會(huì)自動(dòng)生成一列treecolumn,并且它的dataIndextext,并且也自動(dòng)隱藏了表頭,如果想顯示表頭,可以用hideHeaders配置為false。(LZ注:看到這里extjs3和4的tree已經(jīng)有了本質(zhì)的不同,extjs4的tree本質(zhì)上就是TreeGrid,只是在只有一列的時(shí)候,展現(xiàn)形式為原來(lái)的TreePanel)

      Adding nodes to the tree 添加節(jié)點(diǎn)

      tree的根節(jié)點(diǎn)不是必須在初始化時(shí)設(shè)定。后續(xù)再添加也可以:

      var tree = Ext.create('Ext.tree.Panel');
      tree.setRootNode({
          text: 'Root',
          expanded: true,
          children: [{
              text: 'Child 1',
              leaf: true
          }, {
              text: 'Child 2',
              leaf: true
          }]
      });
      

      盡管對(duì)于很小的樹(shù)只有默認(rèn)幾個(gè)靜態(tài)節(jié)點(diǎn)的,這種直接在代碼里面配置的方式很方便,但是大多數(shù)情況tree還是有很多節(jié)點(diǎn)的。讓我們看一下如何通過(guò)程序添加節(jié)點(diǎn)。

      var root = tree.getRootNode();
      
      var parent = root.appendChild({
          text: 'Parent 1'
      });
      
      parent.appendChild({
          text: 'Child 3',
          leaf: true
      });
      
      parent.expand();
      

      每一個(gè)不是葉節(jié)點(diǎn)的節(jié)點(diǎn)都有一個(gè)appendChild方法,這個(gè)方法接收一個(gè)Node類型,或者是Node的配置參數(shù)的參數(shù),返回值是新添加的節(jié)點(diǎn)對(duì)象。上面的例子中也調(diào)用了expand方法展開(kāi)這個(gè)新的父節(jié)點(diǎn)。

      extjs-4-trees-append-children.png

      上面的例子利用內(nèi)聯(lián)的方式,亦可:

      var parent = root.appendChild({
          text: 'Parent 1',
          expanded: true,
          children: [{
              text: 'Child 3',
              leaf: true
          }]
      });
      

      有時(shí)我們期望將節(jié)點(diǎn)插入到一個(gè)特定的位置,而不是在最末端添加。除了appendChild方法,Ext.data.NodeInterface還提供了insertBeforeinsertChild方法。

      var child = parent.insertChild(0, {
          text: 'Child 2.5',
          leaf: true
      });
      
      parent.insertBefore({
          text: 'Child 2.75',
          leaf: true
      }, child.nextSibling);
      

      insertChild方法需要一個(gè)節(jié)點(diǎn)位置,新增的節(jié)點(diǎn)將會(huì)插入到這個(gè)位置。insertBefore方法需要一個(gè)節(jié)點(diǎn)的引用,新節(jié)點(diǎn)將會(huì)插入到這個(gè)節(jié)點(diǎn)之前。

      extjs-4-trees-insert-children.png

      NodeInterface也提供了幾個(gè)可以引用到其他節(jié)點(diǎn)的屬性

      • nextSibling
      • previousSibling
      • parentNode
      • lastChild
      • firstChild
      • childNodes

      Loading and Saving Tree Data using a Proxy 加載和保存樹(shù)上的數(shù)據(jù)

      加載和保存樹(shù)上的數(shù)據(jù)比處理扁平化的數(shù)據(jù)要復(fù)雜一點(diǎn),因?yàn)槊總€(gè)字段都需要展示層級(jí)關(guān)系,這一章將會(huì)解釋處理這一復(fù)雜的工作。

      NodeInterface Fields

      使用tree數(shù)據(jù)的時(shí)候,最重要的就是理解NodeInterface是如何工作的。每個(gè)tree節(jié)點(diǎn)都是一個(gè)用NodeInterface裝飾的Model實(shí)例。假設(shè)有個(gè)Person Model,它有兩個(gè)字段idname

      Ext.define('Person', {
          extend: 'Ext.data.Model',
          fields: [
              { name: 'id', type: 'int' },
              { name: 'name', type: 'string' }
          ]
      });
      

      如果只做這些,Person Model還只是普通的Model,如果取它的字段個(gè)數(shù):

      console.log(Person.prototype.fields.getCount()); //輸出 '2'
      

      但是如果將Person Model應(yīng)用到TreeStore之中后,就會(huì)有些變化:

      var store = Ext.create('Ext.data.TreeStore', {
          model: 'Person',
          root: {
              name: 'Phil'
          }
      });
      
      console.log(Person.prototype.fields.getCount()); //輸出 '24'
      

      TreeStore使用之后,Person多了22個(gè)字段。所有這些字段都是在NodeInterface中定義的,TreeStore初次實(shí)例化Person的時(shí)候,這些字段會(huì)被加入到Person的原型鏈中。

      那這22個(gè)字段都是什么,有什么用處?讓我們簡(jiǎn)要的看一下NodeInterface,它用如下字段裝飾Model,這些字段都是存儲(chǔ)tree相關(guān)結(jié)構(gòu)和狀態(tài)的:

      {name: 'parentId',   type: idType,    defaultValue: null},
      {name: 'index',      type: 'int',     defaultValue: null, persist: false},
      {name: 'depth',      type: 'int',     defaultValue: 0, persist: false},
      {name: 'expanded',   type: 'bool',    defaultValue: false, persist: false},
      {name: 'expandable', type: 'bool',    defaultValue: true, persist: false},
      {name: 'checked',    type: 'auto',    defaultValue: null, persist: false},
      {name: 'leaf',       type: 'bool',    defaultValue: false},
      {name: 'cls',        type: 'string',  defaultValue: null, persist: false},
      {name: 'iconCls',    type: 'string',  defaultValue: null, persist: false},
      {name: 'icon',       type: 'string',  defaultValue: null, persist: false},
      {name: 'root',       type: 'boolean', defaultValue: false, persist: false},
      {name: 'isLast',     type: 'boolean', defaultValue: false, persist: false},
      {name: 'isFirst',    type: 'boolean', defaultValue: false, persist: false},
      {name: 'allowDrop',  type: 'boolean', defaultValue: true, persist: false},
      {name: 'allowDrag',  type: 'boolean', defaultValue: true, persist: false},
      {name: 'loaded',     type: 'boolean', defaultValue: false, persist: false},
      {name: 'loading',    type: 'boolean', defaultValue: false, persist: false},
      {name: 'href',       type: 'string',  defaultValue: null, persist: false},
      {name: 'hrefTarget', type: 'string',  defaultValue: null, persist: false},
      {name: 'qtip',       type: 'string',  defaultValue: null, persist: false},
      {name: 'qtitle',     type: 'string',  defaultValue: null, persist: false},
      {name: 'children',   type: 'auto',   defaultValue: null, persist: false}
      

      NodeInterface Fields are Reserved Names 節(jié)點(diǎn)接口的字段都是保留字

      有一點(diǎn)非常重要,就是上面列舉的這些字段都應(yīng)該當(dāng)作保留字段。例如,Model中就不允許有一個(gè)字段叫做parentId了,因?yàn)楫?dāng)Model用在Tree上時(shí),Model的字段會(huì)覆蓋NodeInterface的字段。除非這里有個(gè)合法的需求要覆蓋NodeInterface的字段的持久化屬性。

      Persistent Fields vs Non-persistent Fields and Overriding the Persistence of Fields 持久化字段和非持久化字段,如何覆蓋持久化屬性

      大多數(shù)NodeInterface的字段都默認(rèn)是persist: false不持久化的。非持久化字段在TreeStore做保存操作的時(shí)候不會(huì)被保存。大多數(shù)情況默認(rèn)的配置是符合需求的,但是如果真的需要覆蓋持久化設(shè)置,下面展示了如何覆蓋持久化配置。當(dāng)覆蓋持久化配置的時(shí)候,只改變presist屬性,其他任何屬性都不要修改

      // overriding the persistence of NodeInterface fields in a Model definition
      Ext.define('Person', {
          extend: 'Ext.data.Model',
          fields: [
              // Person fields
              { name: 'id', type: 'int' },
              { name: 'name', type: 'string' }
      
              // override a non-persistent NodeInterface field to make it persistent
              { name: 'iconCls', type: 'string',  defaultValue: null, persist: true },
          ]
      });
      

      讓我們深入的看一下NodeInterface的字段,列舉一下可能需要覆蓋persist屬性的情景。下面的每個(gè)例子都假設(shè)使用了Server Proxy除非提示不使用。(注:這需要有一些server端編程的知識(shí))

      默認(rèn)持久化的:

      • parentId – 用來(lái)指定父節(jié)點(diǎn)的id,這個(gè)字段應(yīng)該總是持久化,不要覆蓋它
      • leaf – 用來(lái)指出這個(gè)節(jié)點(diǎn)是不是葉子節(jié)點(diǎn),因此決定了節(jié)點(diǎn)是不是可以有子節(jié)點(diǎn),最好不要改變它的持久化設(shè)置

      默認(rèn)不持久化的:

      • index – 用來(lái)指出當(dāng)前節(jié)點(diǎn)在父節(jié)點(diǎn)的所有子節(jié)點(diǎn)中的位置,當(dāng)有節(jié)點(diǎn)插入或者移除,它的所有鄰居節(jié)點(diǎn)的位置都會(huì)更新,如果需要,可以用這個(gè)屬性去持久化樹(shù)節(jié)點(diǎn)的排列順序。然而如果服務(wù)器端使用另外的排序方法,最好把這個(gè)字段保留為非持久化的,當(dāng)使用WebStorage Proxy作為存儲(chǔ),且需要保留節(jié)點(diǎn)順序,那一定要設(shè)置為持久化的。如果使用了本地排序,建議設(shè)置非持久化,因?yàn)楸镜嘏判驎?huì)改變節(jié)點(diǎn)的index屬性
      • depth 用來(lái)存儲(chǔ)節(jié)點(diǎn)在樹(shù)中的層級(jí),如果server需要保存節(jié)點(diǎn)層級(jí)請(qǐng)開(kāi)啟持久化。使用WebStorage Proxy的時(shí)候建議不要持久化,會(huì)多占用存儲(chǔ)空間。
      • checked 如果在tree使用checkbox特性,看業(yè)務(wù)需求來(lái)開(kāi)啟持久化
      • expanded 存儲(chǔ)節(jié)點(diǎn)的展開(kāi)收起狀態(tài),要不要持久化看業(yè)務(wù)需求
      • expandable 內(nèi)部使用,不要變更持久化配置
      • cls 用來(lái)給節(jié)點(diǎn)增加css類,看業(yè)務(wù)需求
      • iconCls 用來(lái)給節(jié)點(diǎn)icon增加css類,看業(yè)務(wù)需求
      • icon 用來(lái)自定義節(jié)點(diǎn),看業(yè)務(wù)需求
      • root 對(duì)根節(jié)點(diǎn)的引用,不要變動(dòng)配置
      • isLast 標(biāo)識(shí)最后一個(gè)節(jié)點(diǎn),此配置一般不需要變動(dòng)
      • isFirst 標(biāo)識(shí)第一個(gè)節(jié)點(diǎn),此配置一般不需要變動(dòng)
      • allowDrop 用來(lái)標(biāo)識(shí)可放的節(jié)點(diǎn),此配置不要?jiǎng)?/li>
      • allowDrag 用來(lái)標(biāo)識(shí)可拖的節(jié)點(diǎn),此配置不要?jiǎng)?/li>
      • loaded 用來(lái)標(biāo)識(shí)子節(jié)點(diǎn)是否加載完成,此配置不要?jiǎng)?/li>
      • loading 用來(lái)標(biāo)識(shí)子節(jié)點(diǎn)是否正在加載中,此配置不要?jiǎng)?/li>
      • href 用來(lái)指定節(jié)點(diǎn)鏈接,此配置看業(yè)務(wù)需求變動(dòng)
      • hrefTarget 節(jié)點(diǎn)鏈接的target,此配置看業(yè)務(wù)需求變動(dòng)
      • qtip 指定tooltip文字,此配置看業(yè)務(wù)需求變動(dòng)
      • qtitle指定tooltip的title,此配置看業(yè)務(wù)需求變動(dòng)
      • children 內(nèi)部使用,不要?jiǎng)?/li>

      Loading Data 加載數(shù)據(jù)

      有兩種加載數(shù)據(jù)的方式。一次性加載全部節(jié)點(diǎn)和分步加載,當(dāng)節(jié)點(diǎn)過(guò)多時(shí),一次加載會(huì)有性能問(wèn)題,而且不一定每個(gè)節(jié)點(diǎn)都用到。動(dòng)態(tài)分步加載是指在父節(jié)點(diǎn)展開(kāi)的時(shí)候加載子節(jié)點(diǎn)。

      Loading the Entire Tree 一次加載

      Tree的內(nèi)部實(shí)現(xiàn)是只有節(jié)點(diǎn)展開(kāi)的時(shí)候加載數(shù)據(jù)。然而全部的層級(jí)關(guān)系可以通過(guò)一個(gè)嵌套的數(shù)據(jù)結(jié)構(gòu)一次全部加載,只要配置root節(jié)點(diǎn)是展開(kāi)的即可

      Ext.define('Person', {
          extend: 'Ext.data.Model',
          fields: [
              { name: 'id', type: 'int' },
              { name: 'name', type: 'string' }
          ],
          proxy: {
              type: 'ajax',
              api: {
                  create: 'createPersons',
                  read: 'readPersons',
                  update: 'updatePersons',
                  destroy: 'destroyPersons'
              }
          }
      
      });
      
      var store = Ext.create('Ext.data.TreeStore', {
          model: 'Person',
          root: {
              name: 'People',
              expanded: true
          }
      });
      
      Ext.create('Ext.tree.Panel', {
          renderTo: Ext.getBody(),
          width: 300,
          height: 200,
          title: 'People',
          store: store,
          columns: [
              { xtype: 'treecolumn', header: 'Name', dataIndex: 'name', flex: 1 }
          ]
      });
      

      假設(shè)readPersons返回?cái)?shù)據(jù)如下

      {
          "success": true,
          "children": [
              { "id": 1, "name": "Phil", "leaf": true },
              { "id": 2, "name": "Nico", "expanded": true, "children": [
                  { "id": 3, "name": "Mitchell", "leaf": true }
              ]},
              { "id": 4, "name": "Sue", "loaded": true }
          ]
      }
      

      最終形成的樹(shù)就是這樣

      extjs-4-trees-bulk-load.png

      需要注意的是:

      • 所有非葉子節(jié)點(diǎn),但是又沒(méi)有子節(jié)點(diǎn)的,例如上面圖中的Sue,服務(wù)器端返回的數(shù)據(jù)必須loaded屬性設(shè)置為true,否則這個(gè)節(jié)點(diǎn)會(huì)變成可展開(kāi)的,并且會(huì)嘗試向服務(wù)器請(qǐng)求它的子節(jié)點(diǎn)數(shù)據(jù)
      • 另外一個(gè)問(wèn)題,既然loaded是個(gè)默認(rèn)不持久化的屬性,上面一條說(shuō)了服務(wù)器端要返回loaded為true,那么服務(wù)器端的其他返回內(nèi)容也會(huì)影響tree的其他屬性,比如expanded,這就需要注意了,服務(wù)器返回的有些數(shù)據(jù)可能會(huì)導(dǎo)致錯(cuò)誤,比如如果服務(wù)器返回的數(shù)據(jù)帶有root,和可能會(huì)導(dǎo)致錯(cuò)誤。通常建議除了loadedexpanded,服務(wù)器端不要返回其他會(huì)被樹(shù)利用的屬性。

      Dynamically Loading Children When a Node is Expanded 節(jié)點(diǎn)展開(kāi)時(shí)動(dòng)態(tài)加載

      對(duì)于節(jié)點(diǎn)非常多的樹(shù),通常期望動(dòng)態(tài)加載,當(dāng)點(diǎn)擊父節(jié)點(diǎn)的展開(kāi)icon時(shí)再向服務(wù)器請(qǐng)求子節(jié)點(diǎn)數(shù)據(jù)。例如上面的例子中假設(shè)Sue沒(méi)有被服務(wù)器端返回的數(shù)據(jù)設(shè)置為loaded true,那么當(dāng)它的展開(kāi)icon點(diǎn)擊時(shí),樹(shù)的proxy會(huì)嘗試向讀取api readPersons請(qǐng)求一個(gè)這樣的url

      /readPersons?node=4
      

      這意思是告訴服務(wù)器取得id為4的節(jié)點(diǎn)的子節(jié)點(diǎn),返回的數(shù)據(jù)格式跟一次加載相同:

      {
          "success": true,
          "children": [
              { "id": 5, "name": "Evan", "leaf": true }
          ]
      }
      

      現(xiàn)在樹(shù)會(huì)變成這樣:

      extjs-4-trees-dynamic-load.png

      Saving Data 保存數(shù)據(jù)

      創(chuàng)建、更新、刪除節(jié)點(diǎn)都由Proxy自動(dòng)無(wú)縫的處理了。

      Creating a New Node 創(chuàng)建新節(jié)點(diǎn)

      // Create a new node and append it to the tree:
      var newPerson = Ext.create('Person', { name: 'Nige', leaf: true });
      store.getNodeById(2).appendChild(newPerson);
      

      由于Model中定義過(guò)proxy,Model的save方法可以用來(lái)持久化節(jié)點(diǎn)數(shù)據(jù):

      newPerson.save();
      

      Updating an Existing Node 更新節(jié)點(diǎn)

      store.getNodeById(1).set('name', 'Philip');
      

      Removing a Node 刪除節(jié)點(diǎn)

      store.getRootNode().lastChild.remove();
      

      Bulk Operations 批處理

      也可以等創(chuàng)建、更新、刪除了若干個(gè)節(jié)點(diǎn)之后,由TreeStore的sync方法一次保存全部

      store.sync();
      

      更多教程

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多