-->

Why doesn't a store declared in a ViewModel ge

2019-07-09 10:28发布

问题:

This question is related to Trying to bind a store to a ViewModel, but is a different question.

I'm declaring a store in a viewmodel like this:

Ext.define('Mb.view.rma.DetailsModel', {
    extend: 'Ext.app.ViewModel',
    alias: 'viewmodel.rma-details',
    requires: ['Mb.model.rma.Detail'],
    data: {
        id: 0
    },
    stores:{
        details: {
            //store: 'rma.Details',
            type: 'rmaDetails', // correction as suggested by @scebotari
            filters: [{
                property: 'rma',
                value: '{id}'
            }],
            remoteFilter: true
        }
    }
});

When I instantiate the view, the value id is correctly updated in the viewmodel (I can see this because the View reflects it through the bound title):

Ext.define('Mb.view.rma.Details', {
    extend: 'Ext.grid.Panel',
    requires: [
        'Mb.view.rma.DetailsModel'
    ],
    viewModel: {
        type: 'rma-details'
    },
    bind: {
        title: 'Retour n° {id}',
        store: '{details}'
    },

The problem I'm facing is that the store does not get loaded, even though there is the remoteFilter: true property in the viewmodel (setting remoteFilter: true in the store class instead of the viewmodel does not change the behavior).

To complete the code, here is the store (nothing special):

Ext.define('Mb.store.rma.Details', {
    extend: 'Ext.data.Store',
    model: 'Mb.model.rma.Detail',
    alias: 'rmaDetails', // correction as suggested by @scebotari
    proxy: {
        (...)
    },
    remoteFilter: true
});

Main question: Why doesn't the store get loaded ?

Subsidiary question: It looks as a frequent problem to show a details grid like the lines of an invoice for instance. I'm not sure if what I'm trying is the recommended approach using MVVM for this problem. MVVM seems better than MVC, because it gives the possibility to open more than one details instance at a time. I didn't find an example for this case. Is there a recommended way to solve this problem ?

Notes:

The filter gets applied as it should.

The store {details} doesn't seem to be a chained store. In fact, it becomes a chained store when changing store: 'rma.Details' into source: 'rma.Details' in the viewmodel.

回答1:

As far as I am aware, this is not how you use stores declared in separate classes in the viewmodels.

When declaring a store that you want to use in a view model, you should specify the "alias" config like so:

Ext.define('Mb.store.rma.Details', {
    extend: 'Ext.data.Store',
    model: 'Mb.model.rma.Detail',
    alias: 'store.rmaDetails',
    proxy: {
        (...)
    }
});

And then use this alias in the viewmodel in the "type" store config:

stores:{
    details: {
        type: 'rmaDetails',
        filters: [{
            property: 'rma',
            value: '{id}'
        }],
        remoteFilter: true,
        autoLoad: true
    }
}

I don't know why this is not documented yet. Maybe because this capability was added later (https://www.sencha.com/forum/showthread.php?284012-Use-existing-Store-in-ViewModel).

The data will load automatically when setting autoLoad: true. The store configs in the viewmodel extend the store class store.rmaDetails. Each view instance has its own store instance associated (that is different from the default instance .getStore('rma.Details').