#18217 closed defect (invalid)
modules sharing works strange - all changes are in all parent widgets
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | undecided | Milestone: | tbd |
Component: | Loader | Version: | 1.10.0 |
Keywords: | Cc: | ||
Blocked By: | Blocking: |
Description
I have a one strange issue. I tested it on isolated environment and everything works fine. But in nested structure I am not able to share modules. In some cases I get empty objects or all methods has undefined value but exists.
Problem description:
- module1 for inheritance - sharing, no widget, only module without template, only logic (properties and methods), no constructor, no startup, define and declare are used.
- widget1 define module1 and use it in declare - inheritance, widget1 has template, constructor and startup
- widget2 define module1 and use it in declare - inheritance, widget2 has template, constructor and startup
if widget1 set any property in module1, automatically has same value widget2.
What is wrong? I have this issue on two projects. I thought that it is dgrid bug but it seems that it is dojo module loader/declare bug because dgrid is not used.
Change History (4)
comment:1 Changed 7 years ago by
Owner: | set to [email protected]… |
---|---|
Status: | new → pending |
comment:2 Changed 7 years ago by
Status: | pending → new |
---|
Posting simple short sample for check. Inside startup I set properties to settings. What I set to widget 1 I see in widget 2. What is wrong. In isolated testcase it works fine, independent. In nested structure I have this problem. Using mostly declarative style for rendering/parsing widgets. But this strange behavior has other consequences.
Short sample of module
define(["dojo/_base/declare", "dojo/aspect", "dojo/store/Memory", "dojo/store/Observable", "dijit/Tree", "dijit/tree/ObjectStoreModel", "dijit/tree/dndSource", "dijit/registry", "dojo/_base/lang", "dojo/dom-class" ], function(declare, aspect, Memory, Observable, Tree, ObjectStoreModel, dndSource, registry, lang, domClass) { return declare([], { settings: { data: null, getChildren: function(object) { }, mayHaveChildren: function(item) { } }, method : function() { } }); } );
Short sample of widget 1, see startup
define([ "dojo/_base/declare", "_WidgetTemplate", // contains other modules "dojo/text!./templates/Template.html", "module" ], function(declare, _WidgetTemplate, template, module) { return declare("widget-1", [ _WidgetTemplate, module], { templateString: template, constructor: function(object) { }, startup: function() { this.inherited(arguments); this.settings.data = {name : "neonstalwart"}; } }); });
Short sample of widget 2, see startup
define([ "dojo/_base/declare", "_WidgetTemplate", "dojo/text!./templates/Template.html", "module" ], function(declare, _WidgetTemplate, template, module) { return declare("widget-2", [ _WidgetTemplate, module], { templateString: template, constructor: function(object) { }, startup: function() { this.inherited(arguments); this.settings.data = {name : "bill"}; } }); });
comment:3 Changed 7 years ago by
Resolution: | → invalid |
---|---|
Status: | new → closed |
this is working exactly as expected.
- widget 1 and widget 2 get a reference to the same mixin/class you return from module.
- the
settings
object you've set on the prototype is shared amongst all instances derived from module.
to get around this, you need to avoid putting an object (i.e. settings
) on the prototype. you can either flatten it out and put the data
, getChildren
, and mayHaveChildren
properties directly on your class or you can add some extra code to create a unique settings
object per instance
return declare([], { settings: null, postMixInProperties: function () { this.inherited(arguments); // any settings passed to the constructor would now be at this.settings. // this will use those to override/augment our default settings. // this creates a new settings object per instance // and does not mutate any settings passed in from the user. this.settings = lang.mixin({ data: null, getChildren: function (object) { }, mayHaveChildren: function (item) { } }, this.settings); } });
since there is no bug, i'm closing this ticket. if you need more help to understand what is happening here and why, please seek help via the mailing list, irc, stackoverflow, etc.
comment:4 Changed 7 years ago by
Thanks, it works. This information is very important/useful. I was searching it on internet, but haven't found information that this case can cause a problem and I must use postMixInProperties for this.
do you have any code to go along with this? the best i can guess from your description is that you're not realizing that module1 is shared between the 2 widgets - this is working as expected. think of modules as singletons. once you request a module, if another module requests that same module, they both have a reference to the same object.
does that explain the problem you're seeing?