Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use inherited mixins #666

Merged
merged 16 commits into from
Feb 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions viewer/js/config/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
'viewer/_ConfigMixin', // manage the Configuration
'viewer/_LayoutMixin', // build and manage the Page Layout and User Interface
'viewer/_MapMixin', // build and manage the Map
'viewer/_WidgetsMixin', // build and manage the Widgets
'viewer/_WidgetsMixin' // build and manage the Widgets

'viewer/_WebMapMixin' // for WebMaps
// 'viewer/_WebMapMixin' // for WebMaps
//'config/_customMixin'

], function (
Expand All @@ -43,21 +43,34 @@
_ConfigMixin,
_LayoutMixin,
_MapMixin,
_WidgetsMixin,
_WidgetsMixin

_WebMapMixin
// _WebMapMixin
//_MyCustomMixin

) {
var controller = new (declare([
_ControllerBase,
_ConfigMixin,
var App = declare([

// add custom mixins here...note order may be important and
// overriding certain methods incorrectly may break the app
// First on the list are last called last, for instance the startup
// method on _ControllerBase is called FIRST, and _LayoutMixin is called LAST
// for the most part they are interchangeable, except _ConfigMixin
// and _ControllerBase
//
_LayoutMixin,
_MapMixin,
_WidgetsMixin,
// _WebMapMixin,
_MapMixin,

// configMixin should be right before _ControllerBase so it is
// called first to initialize the config object
_ConfigMixin,

_WebMapMixin
]))();
controller.startup();
// controller base needs to be last
_ControllerBase
]);
var app = new App();
app.startup();
});
})();
54 changes: 37 additions & 17 deletions viewer/js/viewer/_ConfigMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,42 @@ define([
) {

return declare(null, {
loadConfig: function (wait) {

// this will be used to make any inherited methods 'wait'
var waitDeferred;

if (wait) {
waitDeferred = new Deferred();

// if we need to wait for a previous deferred
// wait for it,
wait.then(lang.hitch(this, function () {

// load the config
this.initConfigAsync().then(lang.hitch(this, function () {

// do some stuff
this.initConfigSuccess(arguments);

// resolve
waitDeferred.resolve();
}),
lang.hitch(this, 'initConfigError')
);

}));
} else {

waitDeferred = this.initConfigAsync();
waitDeferred.then(
lang.hitch(this, 'initConfigSuccess'),
lang.hitch(this, 'initConfigError')
);
}
// call any inherited methods or return a deferred
return this.inherited(arguments, [waitDeferred]) || waitDeferred;
},

initConfigAsync: function () {
var returnDeferred = new Deferred();
Expand All @@ -30,10 +66,6 @@ define([

initConfigSuccess: function (config) {
this.config = config;

// in _WidgetsMixin
this.createWidgets(['loading']);

if (config.isDebug) {
window.app = this; //dev only
}
Expand All @@ -43,18 +75,6 @@ define([
current: config.defaultMapClickMode,
defaultMode: config.defaultMapClickMode
};

// in _LayoutMixin
this.initLayout();

// in _WidgetsMixin
this.createWidgets(['layout']);

// in _MapMixin
this.initMapAsync().then(
lang.hitch(this, 'initMapComplete'),
lang.hitch(this, 'initMapError')
);
},

initConfigError: function (err) {
Expand All @@ -64,4 +84,4 @@ define([
});
}
});
});
});
81 changes: 70 additions & 11 deletions viewer/js/viewer/_ControllerBase.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,86 @@
/*eslint no-console: 0*/
define([
'dojo/_base/declare',
'dojo/_base/lang'
'dojo/_base/lang',
'dojo/Deferred'
], function (
declare,
lang
declare, lang, Deferred
) {
return declare(null, {

/**
* A method run before anything else, can be inherited by mixins to
* load and process the config sync or async
* @return {undefined | Deferred} If the operation is async it should return
* a deferred, otherwise it should return the value of `this.inherited(arguments)`
*/
loadConfig: function () {
return this.inherited(arguments);
},
/**
* A method run after the config is loaded but before startup is called
* on mixins
* @return {undefined | Deferred} If the operation is async it should return
* a deferred, otherwise it should return the value of `this.inherited(arguments)`
*/
postConfig: function () {
return this.inherited(arguments);
},
/**
* Start the application mixin chain, once the
* startupDeferred is resolved
* @return {undefined}
*/
startup: function () {
this.inherited(arguments);

// in _ConfigMixin
this.initConfigAsync().then(
lang.hitch(this, 'initConfigSuccess'),
lang.hitch(this, 'initConfigError')
);
// cache the inherited
var inherited = this.getInherited(arguments);

// load config and process it
this.startupDeferred = this.executeSync([
this.loadConfig,
this.postConfig
]);

// wait for any loading to complete
this.startupDeferred.then(lang.hitch(this, function () {

// start up the mixin chain
inherited.apply(this);
}));
},
/**
* executes an array of asynchronous methods synchronously
* @param {Array<function>} methods The array of functions to execute
* @param {Deferred} deferred A deferred created inside the method and resolved once all methods are complete
* @return {Deferred} A deferred resolved once all methods are executed
*/
executeSync: function (methods, deferred) {
deferred = deferred || new Deferred();

// if our list is empty, resolve the deferred and quit
if (!methods || !methods.length) {
deferred.resolve();
return deferred;
}

// execute and remove the method from the list
var result = lang.hitch(this, methods.splice(0, 1)[0])();

// execute our next function once this one completes
if (result) {
result.then(lang.hitch(this, 'executeSync', methods, deferred));
} else {
this.executeSync(methods, deferred);
}
return deferred;

},

//centralized error handler
handleError: function (options) {
if (this.config.isDebug) {
if (typeof (console) === 'object') {
if (typeof(console) === 'object') {
for (var option in options) {
if (options.hasOwnProperty(option)) {
console.log(option, options[option]);
Expand Down Expand Up @@ -54,4 +113,4 @@ define([
return dest;
}
});
});
});
21 changes: 18 additions & 3 deletions viewer/js/viewer/_LayoutMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ define([
'dojo/dom-class',
'dojo/dom-geometry',
'dojo/sniff',
'dojo/Deferred',

'put-selector',

Expand All @@ -33,6 +34,7 @@ define([
domClass,
domGeom,
has,
Deferred,

put,

Expand Down Expand Up @@ -61,14 +63,24 @@ define([
}
},
collapseButtons: {},
postConfig: function () {
this.layoutDeferred = new Deferred();
return this.inherited(arguments);
},

initLayout: function () {
startup: function () {
this.config.layout = this.config.layout || {};

this.addTopics();
this.addTitles();
this.detectTouchDevices();
this.initPanes();

this.mapDeferred.then(lang.hitch(this, 'createPanes'));

// resolve the layout deferred
this.layoutDeferred.resolve();
this.inherited(arguments);
},

// add topics for subscribing and publishing
Expand Down Expand Up @@ -171,7 +183,7 @@ define([
panes[key] = lang.mixin(this.defaultPanes[key], panes[key]);
}
}
// where to place the buttons
// where to place the buttons
// either the center map pane or the outer pane?
this.collapseButtonsPane = this.config.collapseButtonsPane || 'outer';

Expand Down Expand Up @@ -251,7 +263,10 @@ define([
}

if (!suppressEvent) {
topic.publish('viewer/onTogglePane', {pane: id, show: show});
topic.publish('viewer/onTogglePane', {
pane: id,
show: show
});
}
}
}
Expand Down
51 changes: 34 additions & 17 deletions viewer/js/viewer/_MapMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,51 @@ define([

return declare(null, {

postConfig: function () {
this.mapDeferred = new Deferred();
return this.inherited(arguments);
},

startup: function () {
this.inherited(arguments);
this.layoutDeferred.then(lang.hitch(this, 'initMapAsync'));
},

initMapAsync: function () {
var returnDeferred = new Deferred();
var returnWarnings = [];

this._createMap(returnWarnings).then(
this.createMap(returnWarnings).then(
lang.hitch(this, '_createMapResult', returnDeferred, returnWarnings)
);
returnDeferred.then(lang.hitch(this, 'initMapComplete'));
return returnDeferred;
},

_createMap: function (returnWarnings) {
createMap: function (returnWarnings) {

// mixins override the default createMap method and return a deferred
var result = this.inherited(arguments);
if (result) {
return result;
}

// otherwise we can create the map
var mapDeferred = new Deferred(),
container = dom.byId(this.config.layout.map) || 'mapCenter';

if (this.config.webMapId) {
if (this._initWebMap) {
mapDeferred = this._initWebMap(this.config.webMapId, container, this.config.webMapOptions);
} else {
returnWarnings.push('The "_WebMapMixin" Controller Mixin is required to use a webmap');
this.map = new Map(container, this.config.mapOptions);

// let some other mixins modify or add map items async
var wait = this.inherited(arguments);
if (wait) {
wait.then(function (warnings) {
if (warnings) {
returnWarnings = returnWarnings.concat(warnings);
}
mapDeferred.resolve(returnWarnings);
}
});
} else {
this.map = new Map(container, this.config.mapOptions);
mapDeferred.resolve(returnWarnings);
}
return mapDeferred;
Expand Down Expand Up @@ -194,8 +216,6 @@ define([
}

if (this.map) {
// in _WidgetsMixin
this.createWidgets(['map', 'layer']);

this.map.on('resize', function (evt) {
var pnt = evt.target.extent.getCenter();
Expand All @@ -204,11 +224,8 @@ define([
}, 100);
});

// in _LayoutsMixin
this.createPanes();

// in _WidgetsMixin
this.createWidgets();
// resolve the map deferred
this.mapDeferred.resolve(this.map);
}

},
Expand All @@ -234,4 +251,4 @@ define([
}
}
});
});
});
Loading