[Representation] Minimize scope reuse

When switching among domain objects and/or views, avoid
reusing the same information is scope. The wrong information
in scope can cause various failures in views, such as WTD-1182.
This commit is contained in:
Victor Woeltjen
2015-05-20 16:26:28 -07:00
parent f74199e60f
commit 9b6d8cf1ec
2 changed files with 31 additions and 6 deletions

View File

@ -69,6 +69,9 @@ define(
function lookupPanels(ids) { function lookupPanels(ids) {
var configuration = $scope.configuration || {}; var configuration = $scope.configuration || {};
// Ensure ids is array-like
ids = ids || [];
// Pull panel positions from configuration // Pull panel positions from configuration
rawPositions = shallowCopy(configuration.panels || {}, ids); rawPositions = shallowCopy(configuration.panels || {}, ids);

View File

@ -73,14 +73,17 @@ define(
function link($scope, element, attrs) { function link($scope, element, attrs) {
var activeRepresenters = representers.map(function (Representer) { var activeRepresenters = representers.map(function (Representer) {
return new Representer($scope, element, attrs); return new Representer($scope, element, attrs);
}); }),
toClear = [], // Properties to clear out of scope on change
counter = 0;
// Populate scope with any capabilities indicated by the // Populate scope with any capabilities indicated by the
// representation's extension definition // representation's extension definition
function refreshCapabilities() { function refreshCapabilities() {
var domainObject = $scope.domainObject, var domainObject = $scope.domainObject,
representation = lookup($scope.key, domainObject), representation = lookup($scope.key, domainObject),
uses = ((representation || {}).uses || []); uses = ((representation || {}).uses || []),
myCounter = counter;
if (domainObject) { if (domainObject) {
// Update model // Update model
@ -94,10 +97,16 @@ define(
" for representation ", " for representation ",
$scope.key $scope.key
].join("")); ].join(""));
$q.when( $q.when(
domainObject.useCapability(used) domainObject.useCapability(used)
).then(function (c) { ).then(function (c) {
// Avoid clobbering capabilities from
// subsequent representations;
// Angular reuses scopes.
if (counter === myCounter) {
$scope[used] = c; $scope[used] = c;
}
}); });
}); });
} }
@ -109,8 +118,7 @@ define(
function refresh() { function refresh() {
var domainObject = $scope.domainObject, var domainObject = $scope.domainObject,
representation = lookup($scope.key, domainObject), representation = lookup($scope.key, domainObject),
uses = ((representation || {}).uses || []), uses = ((representation || {}).uses || []);
gestureKeys = ((representation || {}).gestures || []);
// Create an empty object named "representation", for this // Create an empty object named "representation", for this
// representation to store local variables into. // representation to store local variables into.
@ -131,9 +139,19 @@ define(
$log.warn("No representation found for " + $scope.key); $log.warn("No representation found for " + $scope.key);
} }
// Clear out the scope from the last representation
toClear.forEach(function (property) {
delete $scope[property];
});
// Populate scope with fields associated with the current // Populate scope with fields associated with the current
// domain object (if one has been passed in) // domain object (if one has been passed in)
if (domainObject) { if (domainObject) {
// Track how many representations we've made in this scope,
// to ensure that the correct representations are matched to
// the correct object/key pairs.
counter += 1;
// Initialize any capabilities // Initialize any capabilities
refreshCapabilities(); refreshCapabilities();
@ -147,6 +165,10 @@ define(
activeRepresenters.forEach(function (representer) { activeRepresenters.forEach(function (representer) {
representer.represent(representation, domainObject); representer.represent(representation, domainObject);
}); });
// Track which properties we want to clear from scope
// next change object/key pair changes
toClear = uses.concat(['model']);
} }
} }