ExtJS 5 MVVM: Updating Parent's ViewModel from Child's -


my extjs 5 component's viewmodel inheriting data ancestor's viewmodel.

how update parent's viewmodel's data child's perspective? if try childpanel.getviewmodel().set('myprop', 'foo'); creates new instance of myprop on childpanel viewmodel, instead of updating parentpanel's vm. other components using myprop's value different childpanel.

by creating local myprop on child, when parent's myprop changes, child not change it, because of severed relationship.

i want 1 instance of myprop property, , value on parent's viewmodel.

to fix this, seems child vm have know if property inherited or if stored locally, requiring child know correct architecture of application. has know more of application's architecture comfortable with, coupling child parent.


example showing child creating new instance of paneltitle instead of updating parent's:

https://fiddle.sencha.com/#fiddle/1e09

edit: moved button's click event viewcontroller

ext.application({     name: 'fiddle',      launch: function() {          ext.define('childpanel', {             extend: 'ext.panel.panel',             alias: 'widget.childpanel',             controller: 'childpanelcontroller',             bind: {                 title: '{paneltitle}'             },              // first panel has own viewmodel, child of viewport's vm             viewmodel: {                 data: {                     'btntext': 'click change title'                 }             },              items: [{                 xtype: 'button',                 scale: 'large',                 bind: {                     text: '{btntext}'                 },                 listeners: {                     'click': 'onbuttonclick'                 }             }]         });          ext.define('childpanelcontroller', {             extend: 'ext.app.viewcontroller',             alias: 'controller.childpanelcontroller',             onbuttonclick: function(btn) {                 // updates first panel's vm                 this.getviewmodel().set('paneltitle', '<span style="color:red;">now have different titles</span>');                  debugger;                  window.settimeout(function() {                      // setting first panel's vm instead of viewport's,                      // first panel not use viewport's vm `paneltitle` property again                     btn.up('viewport').getviewmodel().set('paneltitle', '<span style="color:green;">and no longer using same vm data</span>');                  }, 500);             }         });            ext.create('ext.container.viewport', {             viewmodel: {                 data: {                     'paneltitle': 'both have same title'                 }             },             layout: 'hbox',             items: [{                 xtype: 'childpanel',                 flex: 1             }, {                 // second panel uses viewport's viewmodel                 xtype: 'panel',                 bind: {                     title: '{paneltitle}'                 },                 flex: 1,                 margin: '0 0 0 25px'             }]         });     } }); 

after talking sencha support, created override ext.app.viewmodel set function.

ext.define('overrides.app.viewmodel', {     override: 'ext.app.viewmodel',      /**      * override adds option update viewmodel "owns" {@link #property-data} property.      * traverse viewmodel tree find ancestor initial viewmodel inherited `path` from.      * if no owner found, updates initial viewmodel.      *      * uses override if `onlyupdateowner` parameter `true`.      *      * @param {boolean} [onlyupdateowner=false] if `true`, uses override update vm `path` stored      * @inheritdoc ext.app.viewmodel#method-set      * @override_ext_version extjs 5.1.2.748      */     set: function (path, value, onlyupdateowner) {         var vm = this,             foundowner = false,             ownervm = vm;          onlyupdateowner = ext.valuefrom(onlyupdateowner, false);          if (onlyupdateowner) {              // find viewmodel initial viewmodel inherited `path` (if did)             {                 // `true` if `path` ***ever*** had value (anything `undefined`)                 if (ownervm.hadvalue && ownervm.hadvalue[path]) {                     break;                 }             } while (ownervm = ownervm.getparent());         }           // reverts initial viewmodel if did not inherit         ownervm = ownervm || vm;          ownervm.callparent([path, value]);     } }); 

it gives developer option update viewmodel source of property.

if cannot find viewmodel "owns" property, falls initially-called-from viewmodel.

it finishes calling original extjs set function proper viewmodel context.


Comments