Blog webdeveloperski Patryk yarpo Jar

Odświeżanie gałęzi drzewa dijit.Tree

Autor wiadomości Wrzesień 9, 2011

W poprzednim wpisie pokazałem jak zbudować drzewo oparte o `dojox.data.JsonRestStore'. W tym wpisie pokażę, jak odświeżać wybraną gałąź tego drzewa.

Scenariusz

Załóżmy, że mamy drzewo, które może być edytowane przez kilka osób równolegle lub też może zmieniać się automatycznie. Jako, że korzystamy z data store'a pozwalającego na lazy loading (ang. późne ładowanie) może się okazać, że dane na serwerze będą inne od tych, jakie przechowujemy lokalnie. Wteyd warto byłoby odświeżyć wybraną gałąź drzewa.

O dziwo nie ma prostej metody `dijit.Tree.refresh(gałąź)' :/. Można jednak napisać krótki kawałek kodu pozwalający uzyskać oczekiwany efekt.

UWAGA (dodane 1 sierpnia 2012 r.): ten sposób niestety nie zawsze działa. Cache przeglądarek jak i same wbudowane w Dojo są na tyle mocne, że nie wszystko udaje się odświeżyć.

Przykład zawarty w tym wpisie jest oparty o kod z wpisu o lazy loadingu dijit.Tree.

Dodajmy globalną funkcję `refresh':

function refresh( item )
{
    var id = (item) ? item.id || item.$ref : dojo.byId('identity').value;
    tree.model.store.fetch({
        query: id,
        onComplete: function(reloaded) {
            var children = reloaded.children || [],
                n = children.length,
                childNodes;
            while(n--)
            {
                refresh( children[n] );
            }
        },
        onError : function() { alert('Wystąpił błąd!'); }
    });
}

Oraz odpowiedni formularz, dzięki któremu będziemy mogli wybrać jaki węzeł (i jego gałąź) chcemy odświeżyć.

<form action="#" onsubmit="refresh(); return false;">
Wybierz węzeł do odświeżenia:
<select id="identity">
<option value="1">Patryk yarpo Jar</option>
<option value="2">Jan</option>
<option value="3">Zdzisiu</option>
<option value="4">Mietek</option>
<option value="5">Józio</option>
<option value="6">Stefan</option>
</select>
<input type="submit" value="odśwież">
</form>

demo online [pobierz zip]

Zasada działania

Wywołujemy metodę `fetch' podając jej, jakie żądanie ma zostać wysłane na serwer (w uproszczeniu. Tak naprawdę równie dobrze moglibyśmy użyć tej samej metody dla odczytania ponownie z data store'a, który nie komunikuje się z serwerem). Funkcja ta za każdym razem wymusi odczytanie świeżych danych z serwera (o co właśnie nam chodzi) i przekaże je do odpowiedniego callbacka.

W callbacku `onComplete' sprawdzamy, czy odczytany item ma dzieci i jeśli tak, odczytujemy również je. Jeśli chciałbyś odczytywać tylko jeden węzeł (bez jego potomków) po prostu usuń while'a.

Stworzenie `dijit.Tree.refresh( dojo.data.item )'

Skoro się rzekło, że można załatać "dziurę" w interfejsie Dojo, to teraz należy ją załatać:

dojo.require("dojox.data.JsonRestStore");
dojo.require("dijit.Tree");

var tree;
dojo.addOnLoad(function() {
    var store = new dojox.data.JsonRestStore({
        target : 'resource.php/',
        labelAttribute : 'name',
        idAttribute : 'id'
    }),
    model = new dijit.tree.ForestStoreModel({
        store: store,
        deferItemLoadingUntilExpand: true,
        query : 'root',
        childrenAttrs: ['children']
    });
    tree = new dijit.Tree({
        model: model,
        showRoot: false,
        refresh : function(item, expand)
        {
           var that = this,
               store = this.model.store;
           store.fetch({
              query: store.getIdentity(item),
              onComplete: function(reloaded)
              {
                  var children = reloaded.children || [],
                      n = children.length,
                      childNodes;
                  if (false !== expand)
                  {
                      while(n--)
                      {
                          that.refresh( children[n] );
                      }
                  }
              },
              onError : function() { alert('Wystąpił błąd!'); }
              })
          }
    }, 'tree');
});
function refresh()
{
    var id = dojo.byId('identity').value;
    tree.model.fetchItemByIdentity({
        identity : id,
        onItem: function(item)
        {
            tree.refresh(item);
        }
    })
}

demo online [pobierz zip]

Reszta kodu pozostaje taka sama jak w poprzednim przypadku.

Nagłówek tej funkcji wyglądałby następująco:

void dijit.Tree.refresh( data.dojo.item item, [boolean expand])
  • Pierwszy argument musi być itemem. W funkcji `refresh()' pokazałem jak go można uzyskać mając id. (obowiązkowy),
  • Parametr `expand' jeśli jest ustawiony na false (i tylko i wyłącznie === `false') blokuje odświeżanie całej gałęzi - odświeżony zostanie tylko jeden węzeł (opcjonalny, domyślnie dla całej gałęzi).

Warto zajrzeć

Komentarze (0) Trackbacks (0)

Brak komentarzy.


Leave a comment

 

Brak trackbacków.