2011-06-24 25 views
11

Testuję extjs 4 i natknąłem się na coś, nie mogę się domyślić.extjs 4 skojarzenia klasy XTemplate

Mam prosty obiekt Stowarzyszenie: Snapshot - hasMany -> Model

Teraz staram się używać XTemplate pokazać tę zależność w widoku komponentu, więc mam mój XTemplate wygląda tak:

Ext.create('Ext.XTemplate', 
'<tpl for=".">', 
'<div class="snapshot" id="{id}">', 
'<h1>{snapshot}</h1>', 
'<p><span class="label">Created: </span>{dateString}</p>', 
'<p><span class="label">Models</span></p>', 
'<tpl for="models">', 
'<p>{name} - {description}</p>', 
'</tpl>', 
'</div>', 
'</tpl>', 
'<div class="x-clear bottompad"></div>' 
); 

A moja odpowiedź JSON wygląda następująco (pokazano tylko 'migawkę' node):

{ 
     "id": 1, 
     "snapshot": "Snapshot 1", 
     "created": 1305806847000, 
     "models": [ 
      { 
       "id": 1, 
       "name": "ABC", 
       "description": "A B C" 
      }, { 

       "id": 111, 
       "name": "ABCDD", 
       "description": "A B C XCXC" 
      } 
     ] 
    } 

As ExtJS 4 w wprowadza koncepcję Modelu I stworzyło modele dla Migawek i Modelu oraz stworzyło powiązanie zgodnie z dokumentami API.

Snapshot model:

Ext.define('Snapshot', { 
    extend: 'Ext.data.Model', 
    fields: [ 
     {name: 'id', type: 'int'}, 
     'snapshot', 
     {name: 'created',type: 'date', dateFormat: 'time' } 

    ], 
    associations:[ 
     {type: 'hasMany', model: 'Model', name: 'models'} 
    ], 
    idProperty: 'id' 
}); 

Modelarski; P

Ext.define('Model', { 
    extend: 'Ext.data.Model', 
    belongsTo: 'Snapshot', 
    fields: [ 
     { name: 'id', type: 'int' }, 
     { name: 'snapshot_id', type: 'int' },    
     'name', 
     'description' 
    ], 
    idProperty: 'id' 
}); 

I to jest mój problem polega - Kiedy ja używam takiej konfiguracji jest wyświetlany żaden z moich modeli, gdy XTemplate jest wykonywany , jednak jeśli usunę asocjacje z modelu migawki i po prostu dodaję inne pole o nazwie "modele", to działa poprawnie.

Jaka jest najlepsza praktyka, aby poprawnie wyświetlać listę modeli podczas korzystania z asocjacji? Czy w tym celu muszę użyć szablonów zagnieżdżonych i niestandardowych funkcji?

Odpowiedz

7

dobre pytanie (+1)

Wydaje wykorzystaniem skojarzenia bezpośrednio w XTemplate nie jest możliwe (dzisiaj), ponieważ XTemplate spodziewa tablicę obiektów. (Kiedy masz skojarzenia, nie jest to już prawdą)

Masz trzy opcje -

  1. pozbyć skojarzeń jakbyś wymienione. (Nie „brzmi” dobrze ale będzie działać)
  2. Jeśli masz widok danych przy użyciu szablonu, zastępują Ext.view.AbstractView.prepareData i utworzyć tablicę obiektów z modeli
  3. Zanim zadzwonisz zastosować, iteracyjne nad snapshotStore.getRange () i (re) generują obiekty z „modele” atrybutu i przekazać tę tablicę do .apply
+0

Jest to rodzaj strzelania we własnej stopy, lubię pojęcia ORM w Sencha , większość języków ma już jakiś rodzaj ORM i widzę, że ta funkcja jest solidnym blokiem ich koncepcji MVC, ale miałem szczerą nadzieję, że to będzie działać od podstaw. Może następne wydanie przyniesie tę funkcjonalność. Na razie myślę, że będę trzymał się koncepcji modeli bez skojarzeń, ponieważ będzie to najmniej bolesny model przejściowy dla mojego projektu. – Greg

+1

Zgadzam się. Ogólnie rzecz biorąc, wiele dobrych rzeczy w ExtJS4, ale nie udało się marnie na aspekt jakości. (nawet dokumentacja jest niekompletna i wiele artykułów zatrzymuje się w połowie podczas tłumaczenia). Patrząc na forum sencha, "światła są włączone, ale nikt nie jest w domu". W każdym razie, jeśli ta odpowiedź ci pomogła, rozważ dodanie lub zaakceptowanie –

+1

Warto zauważyć w przyszłych przeglądarkach, że metoda prepareData (zgodnie z 4.1 beta2) teraz używa metody getAssociatedData i stosuje je do zwróconego obiektu danych. – Stuart

0

można słuchać na razie store.load i dodać powiązanych danych z powrotem do rekordu magazynu, a następnie szablon będzie działać (Zrobiłem to używając RowExpander's rowBodyTpl).

listeners: { 
    load: function(store,storeRecs) { 
     var i,r; 
     for (i=0;i<storeRecs.length;i++) { 
      r = storeRecs[i]; 
      r.data.subItem = r.getAssociatedData().subItem; 
     } 
    } 
} 
-1

z mojego bardzo niedawnego doświadczenia, nie powinieneś mieć problemów, jeśli nie pracujesz przez sklepy. Przykład XTemplate z dokumentacji ExtJS 4 działa dobrze (przynajmniej dla mnie). Możesz dodać model dla tych danych, a przykład będzie pracował.

Próbowałem zrobić to samo poprzez sklep. Po przekazaniu danych store.first(). Do metody nadpisywania (...) XTemplate, powiązania nie znajdują się w tej strukturze. można sprawdzić w poniższym kodzie:

var data = { 
    name : 'Tommy Maintz', 
    title : 'Lead Developer', 
    company : 'Sencha Inc.', 
    email : '[email protected]', 
    address : '5 Cups Drive', 
    city : 'Palo Alto', 
    state : 'CA', 
    zip : '44102', 
    drinks : ['Coffee', 'Soda', 'Water'], 
    kids : [{ 
       name : 'Joshua', 
       age : 3 
      }, { 
       name : 'Matthew', 
       age : 2 
      }, { 
       name : 'Solomon', 
       age : 0 
      }] 
}; 



var kidsModelProps = { 
    extend: "Ext.data.Model", 
    fields: [ 
     "name", 
     {name: "age", type: "int"} 
    ] 
} 
Ext.define ("KidsModel", kidsModelProps) 

var datamodelProps = { 
    extend: "Ext.data.Model", 
    fields: [ 
     "name", "title", "company", "email", "address", 
     "city", "state", "zip", "drinks" 
    ], 

    hasMany: {name: "thekids", model: "KidsModel"}, 

    proxy: { 
     type: "memory", 
     reader: { 
      type: "json" 
     } 
    } 
} 
Ext.define ("DataModel", datamodelProps) 


var kidsStore = new Ext.data.Store({ 
    data: data, 
    storeId: "kidsStore", 
    model: "DataModel" 

}) 

var tpl = new Ext.XTemplate(
    '<p>Name: {name}</p>', 
    '<p>Title: {title}</p>', 
    '<p>Company: {company}</p>', 
    '<p>Kids: ', 
    '<tpl for="kids">',  // interrogate the kids property within the data 
     '<p>{name}</p>', 
    '</tpl></p>' 
); 

Ext.onReady(function() { 
    var thePanel = Ext.create ("Ext.panel.Panel", { 
     html: "<b>Viewport tpl-test: build with separated files</b>", 
     border: 10, 
     height: 500, 
     layout: { 
      type: 'vbox', 
      align: 'center' 
     }, 
     renderTo: Ext.getBody(), 
     bodyStyle: "background-color: yellow", 

     items: [] 

    }) 
    var someData = kidsStore.first().data 
    tpl.overwrite (thePanel.body, someData) 
} 

Można również mogą spróbować (aby zobaczyć, jak źle XTemplate-store-stowarzyszenia działają) przy http://www.sencha.com/forum/showthread.php?127320-FIXED-EXTJSIV-242-multiple-HasMany-association-conflict-in-XTemplate.

Niestety nie zapewniają rozwiązania: (

chcąc

3

należy podkreślić, że z 4.1 zapis Model ten sposób zwany getData(), która, jeżeli zostanie to za pomocą getData(true) również zwrócić powiązane dane

+0

A jak to pomaga? – oldwizard

2

Całkowicie zgadzam się, że idealnym rozwiązaniem byłoby, aby szablony wyglądały w ten sposób, ale w rzeczywistości bardzo łatwo jest uzyskać szablon do robienia tego, co chcesz, dzięki skojarzeniom. Modele przechowują wszystkie swoje pola w obrębie właściwości zwanej danymi i skojarzeniami. na poziomie katalogu głównego z konwencją: assoc iationName + "Store". Dlatego wszystko, co musisz zrobić, to napisać szablon następująco:

var template = Ext.create('Ext.XTemplate', 
    '<tpl for=".">', 
     '<div class="snapshot" id="{data.id}">', 
      '<h1>{data.snapshot}</h1>', 
      '<p><span class="label">Created: </span>{data.created}</p>', 
      '<p><span class="label">Models</span></p>', 
      '<tpl for="modelsStore">', 
       '<p>{data.name} - {data.description}</p>', 
      '</tpl>', 
     '</div>', 
    '</tpl>', 
    '<div class="x-clear bottompad"></div>' 
); 
+1

To nie działa. –

+0

Spróbuj zamiast ' '

{NAME} - {description}

',' – Grgur

0

Jak @Izhaki mówi użyć getData (prawdziwy) na płycie, aby przekazać dane do szablonu, a następnie zrobić odmianę co mówi @Aaron pętli przez dane. Na przykład, jeśli szablon jest częścią pojemnika:

//... 
tpl: //your tpl 
data: record.getData(true) 
//.... 

Szablon ten fragment powinien działać prawidłowo:

'<tpl for="models">', 
'<p>{name} - {description}</p>', 
'</tpl>' 
+0

Jeśli pracujesz w sklepie (masz więcej niż jeden model) to nie działa. – oldwizard