javascriptextjsmvvmextjs6dynamic-class-creation

Viewmodel attribute 'links' cannot find the model type


While trying to execute the following code on show() we get an exception that the links attribute cannot find the model either if it is specified by class or if it is specified by entityName.

Ext.define('myapp.view.film.FilmsViewController', {
//extend: 'myapp.view.base.ViewController',
extend: 'Ext.app.ViewController',

alias: 'controller.films',

onAdd: function(button, event, options) {
    this.createDialog(null)
},

createDialog: function(record) {
    var me = this;
    var view = me.getView();    //here is film panel

    me.isEdit = !!record;   //convert record to boolean

    me.dialog = view.add({ //#3
        xtype: 'filmwindow',
        viewModel: { //#4
            data: { //#5
                title: record ? 'Edit: ' + record.get('title') : 'Add New Film',
            },
            links: { //#6
                currentFilm: record || { //#7
                    //type: 'Film',
                    type: 'myapp.model.film.Film',
                    create: true
                }
            }
        },
        //session: true
    });
    me.dialog.show();
},

If we comment the links part of the code the rest is working ok.

Here is the interesting part of the exception:

[E] Ext.app.ViewModel.getRecord(): Invalid model name: myapp.model.film.Film
log @ ext-all-rtl-debug.js?_dc=1446847440066:9121
Ext.apply.raise @ ext-all-rtl-debug.js?_dc=1446847440066:2606
Ext.raise @ ext-all-rtl-debug.js?_dc=1446847440066:2691
Ext.define.privates.getRecord @ ext-all-rtl-debug.js?_dc=1446847440066:99865
Ext.define.linkTo @ ext-all-rtl-debug.js?_dc=1446847440066:99748
Ext.define.privates.applyLinks @ ext-all-rtl-debug.js?_dc=1446847440066:100120

If you dive into the source code you will find that the if statement that checks whether myapp.model.film.Film is a class fails..


Solution

  • After spending more than an entire day and using our wildest imagination we managed to figure out what is going on:

    First of all check this link: https://www.sencha.com/forum/showthread.php?299699-Any-use-of-a-model-schema-breaks-Tree-model-even-if-not-extending.&p=1118964&viewfull=1#post1118964

    You will find out that if you use more than one schema in your source code for no apparent reason these schemas conflict with each other and you are forced to provide a unique schema id.

    Now this custom configuration should be propagated to all other configurations meaning that ViewModels will NOT work unless you specify the schema id that is going to be used.

    In other words view model will only work if you add a schema like this:

    viewModel: {
            schema: "youruniqueschemaid",
    
            data: {
                title: record ? 'Edit: ' + record.get('title') : 'Add New Film',
            },
            links: {
                currentFilm: record || {
                    //type: 'Film',
                    type: 'myapp.model.film.Film',
                    create: true
                }
            }
        }
    

    Yes the type attribute inside the links could not be more misleading!

    You can also use the, shorter version, type: "Film" if you have set the entityName attribute inside the model as Film.

    Refactor now

    What Sencha should have done instead is force all developers to set the schema explicitly inside a ViewModel and use null if the model is not setup using a schema.

    Of course as you can understand solving such an issue could not be done by diving into documentation nor diving inside the source code but rather using a wild guess of what kind of crazy conventions have been used.

    In general the framework should be more explicit.