diff --git a/platform/features/layout/res/templates/frame.html b/platform/features/layout/res/templates/frame.html
index 808603a84a..df4e3390ad 100644
--- a/platform/features/layout/res/templates/frame.html
+++ b/platform/features/layout/res/templates/frame.html
@@ -35,7 +35,7 @@
+ mct-object="representation.selected.key && domainObject">
\ No newline at end of file
diff --git a/platform/features/layout/src/LayoutController.js b/platform/features/layout/src/LayoutController.js
index 4e9de17618..fc6c8aafba 100644
--- a/platform/features/layout/src/LayoutController.js
+++ b/platform/features/layout/src/LayoutController.js
@@ -90,6 +90,10 @@ define(
function lookupPanels(ids) {
var configuration = $scope.configuration || {};
+ // ids is read from model.composition and may be undefined;
+ // fall back to an array if that occurs
+ ids = ids || [];
+
// Pull panel positions from configuration
rawPositions = shallowCopy(configuration.panels || {}, ids);
diff --git a/platform/representation/src/MCTRepresentation.js b/platform/representation/src/MCTRepresentation.js
index 6008e515e3..d93e42b957 100644
--- a/platform/representation/src/MCTRepresentation.js
+++ b/platform/representation/src/MCTRepresentation.js
@@ -93,15 +93,18 @@ define(
function link($scope, element, attrs) {
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
// representation's extension definition
function refreshCapabilities() {
var domainObject = $scope.domainObject,
representation = lookup($scope.key, domainObject),
- uses = ((representation || {}).uses || []);
+ uses = ((representation || {}).uses || []),
+ myCounter = counter;
if (domainObject) {
// Update model
@@ -115,10 +118,16 @@ define(
" for representation ",
$scope.key
].join(""));
+
$q.when(
domainObject.useCapability(used)
).then(function (c) {
- $scope[used] = c;
+ // Avoid clobbering capabilities from
+ // subsequent representations;
+ // Angular reuses scopes.
+ if (counter === myCounter) {
+ $scope[used] = c;
+ }
});
});
}
@@ -130,8 +139,7 @@ define(
function refresh() {
var domainObject = $scope.domainObject,
representation = lookup($scope.key, domainObject),
- uses = ((representation || {}).uses || []),
- gestureKeys = ((representation || {}).gestures || []);
+ uses = ((representation || {}).uses || []);
// Create an empty object named "representation", for this
// representation to store local variables into.
@@ -152,9 +160,19 @@ define(
$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
// domain object (if one has been passed in)
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
refreshCapabilities();
@@ -168,6 +186,10 @@ define(
activeRepresenters.forEach(function (representer) {
representer.represent(representation, domainObject);
});
+
+ // Track which properties we want to clear from scope
+ // next change object/key pair changes
+ toClear = uses.concat(['model']);
}
}
diff --git a/platform/representation/test/MCTRepresentationSpec.js b/platform/representation/test/MCTRepresentationSpec.js
index cb5820a065..43c9104a94 100644
--- a/platform/representation/test/MCTRepresentationSpec.js
+++ b/platform/representation/test/MCTRepresentationSpec.js
@@ -181,6 +181,25 @@ define(
// Should have gotten a warning - that's an unknown key
expect(mockLog.warn).toHaveBeenCalled();
});
+
+ it("clears out obsolete peroperties from scope", function () {
+ mctRepresentation.link(mockScope, mockElement);
+
+ mockScope.key = "def";
+ mockScope.domainObject = mockDomainObject;
+ mockDomainObject.useCapability.andReturn("some value");
+
+ // Trigger the watch
+ mockScope.$watch.calls[0].args[1]();
+ expect(mockScope.testCapability).toBeDefined();
+
+ // Change the view
+ mockScope.key = "xyz";
+
+ // Trigger the watch again; should clear capability from scope
+ mockScope.$watch.calls[0].args[1]();
+ expect(mockScope.testCapability).toBeUndefined();
+ });
});
}
);
\ No newline at end of file