2015-10-02 11 views
6

Ich bin ziemlich neu Ext JS und versuchen, eine MultiSelect in eine Panel einzubetten.Wie binden Sie ViewModel Store an View?

Die ViewModel hat eine stores Eigenschaft, wie Sie hier sehen können:

Ext.define('TEST.view.controls.search.SearchFilterModel', { 
    extend: 'Ext.app.ViewModel', 
    alias: 'viewmodel.filter', 
    data: { 
     title: '' 
    }, 
    stores: { 
     test: { 
      fields: [ 'id', 'name' ], 
      proxy: { 
       type: 'ajax', 
       url: 'api/test', 
       reader: 'array' 
      }, 
      autoLoad: true 
     } 
    } 
}); 

Ich möchte, dass wie dies in meinem View binden:

viewModel: { 
    type: 'filter' 
}, 


layout: 'fit', 
border: 1, 
plain: true, 
scrollable: 'y', 
layout: 'fit', 


bind: { 
    title: '{title}', 
}, 


items: { 
    xtype: 'multiselect', 
    scrollable: false, 
    allowBlank: true, 
    ddReorder: true, 
    bind: { 
    store: '{test}' 
    }, 
    valueField: 'id', 
    displayField: 'name' 
} 

In diesem Fall wird die store endet als null obwohl und keine Daten in das Widget geladen werden. Anstatt den Speicher zu binden, wenn ich ihn nur in der Ansicht fest codiere, funktioniert es.

Wer sieht, was das Problem ist?

+0

Warum haben Sie entschieden, dass der Laden null ist? Für mich ist das mitgelieferte Snippet gut und sollte funktionieren. Sie sollten den ganzen Code der Ansicht zur Verfügung stellen, das Beste wird sein, jfiddle oder sencha fiddle zur Verfügung zu stellen, um das Problem zu demonstrieren. – yorlin

+0

@yorlin - Danke, ich werde versuchen, eine Sencha-Geige zusammenzustellen. Der Fehler war 'Uncaught TypeError: Kann die Eigenschaft 'autoCreated' von null ' – david

Antwort

6

Sie können ein leeres Objekt als Speicher übergeben zusätzlich den Laden zu binden, auf diese Weise die initComponent arbeiten, zum Beispiel:

{ 
    xtype: 'multiselect', 
    fieldLabel: 'Multiselect', 
    store: {}, 
    bind: { 
     store: '{test}' 
    }, 
    valueField: 'id', 
    displayField: 'name' 
} 

Arbeits Beispiel: https://fiddle.sencha.com/#fiddle/ur8

+0

Glaubst du, das ist ein Fehler oder einfach eine undokumentierte Kuriosität? Ist das überhaupt üblich, dass Sie zweimal so "speichern" müssen? – david

+0

Wenn Sie einen Speicher binden, erstellt extjs zunächst einen leeren Speicher (nicht null, aber einen temporären Speicher) und bindet dann einen normalen Speicher. Das Problem besteht darin, dass die Bindung asynchron und verzögert erfolgt. Die Frage ist, wann Sie auf Ihr Geschäft zugreifen möchten. Es kann sein, dass Sie versuchen, auf den Speicher zuzugreifen, wenn extjs selbst bei leerem Speicher nicht bereit ist. – yorlin

+0

@yorlin - Das macht Sinn, aber ich denke, das ist ein Implementierungsdetail, das neue extjs Entwickler nicht wissen sollten. Und es erfordert die oben genannte redundante Syntax, die sich auf den "Speicher" bezieht. – david

1

Es ist ein häufiges Problem. Solange Sie den Proxy im Laden verwenden, müssen Sie den Laden nach der Ansicht laden. Grundsätzlich fügen Sie diese zu Ihrer View:

listeners: { 
      afterrender: function(view) { 
       this.getViewModel().getStore('{test}').load(); // this will provide proxy is being loaded 
      } 
      } 

Edit: Ich habe nicht bemerkt, Sie schon die autoLoad: true setzen. Nach einigen Nachforschungen muss die Multiselect-Komponente während des Renderns "Objekt speichern" erhalten. Deshalb erhalten Sie den Fehler 'autoCreated'. Ich meine, bevor Multiselect erstellt wird, muss sein Speicher erstellt werden. In diesem Fall wird die Multiselect-Komponente zuerst erstellt, dann wird der Speicher an Multiselect gebunden. Um dieses Problem zu beheben Sie bitte diese Geige überprüfen: https://fiddle.sencha.com/#fiddle/uqu

listeners: { 
       afterrender: function(view) { 
        view.add({ 
         xtype: 'multiselect', 
         scrollable: false, 
         allowBlank: true, 
         ddReorder: true, 
         fieldLabel: 'Multiselect', 
         store: view.getViewModel().getStore('test'), // comment to get autoCreated error 
         valueField: 'id', 
         displayField: 'name' 
        }); 
       } 
      }, 
+0

+1 nicht lesen, aber ich mag die andere Lösung ein wenig besser. Obwohl keiner sehr befriedigend ist. Scheint mir wie ein Käfer. – david