[Forms] Use ng-model for tree state

Use ng-model when communicating state to/from the
tree in browse mode. This will simplify implementation
of the Locator control, which also uses a tree, but
which should not set navigation state. WTD-593.
This commit is contained in:
Victor Woeltjen 2014-12-03 13:18:51 -08:00
parent 80ba6f4da3
commit e04b9828ea
6 changed files with 44 additions and 45 deletions

View File

@ -1,6 +1,6 @@
<div content="jquery-wrapper" class="abs holder-all browse-mode"> <div content="jquery-wrapper" class="abs holder-all browse-mode">
<mct-include key="'topbar-browse'"></mct-include> <mct-include key="'topbar-browse'"></mct-include>
<div class="holder browse-area outline abs" ng-controller="BrowseController as browse"> <div class="holder browse-area outline abs" ng-controller="BrowseController">
<div class='split-layout vertical contents abs'> <div class='split-layout vertical contents abs'>
<div class='split-pane-component treeview pane' style="width: 200px;"> <div class='split-pane-component treeview pane' style="width: 200px;">
<mct-representation key="'create-button'" mct-object="navigatedObject"> <mct-representation key="'create-button'" mct-object="navigatedObject">
@ -8,7 +8,7 @@
<div class='holder tree-holder abs'> <div class='holder tree-holder abs'>
<mct-representation key="'tree'" <mct-representation key="'tree'"
mct-object="domainObject" mct-object="domainObject"
parameters="{callback: browse.setNavigation}"> ng-model="treeModel">
</mct-representation> </mct-representation>
</div> </div>
</div> </div>

View File

@ -24,6 +24,7 @@ define(
// that is currently navigated-to. // that is currently navigated-to.
function setNavigation(domainObject) { function setNavigation(domainObject) {
$scope.navigatedObject = domainObject; $scope.navigatedObject = domainObject;
$scope.treeModel.selectedObject = domainObject;
} }
// Load the root object, put it in the scope. // Load the root object, put it in the scope.
@ -48,30 +49,22 @@ define(
} }
}); });
// Provide a model for the tree to modify
$scope.treeModel = {
selectedObject: navigationService.getNavigation()
};
// Listen for changes in navigation state. // Listen for changes in navigation state.
navigationService.addListener(setNavigation); navigationService.addListener(setNavigation);
// Also listen for changes which come from the tree
$scope.$watch("treeModel.selectedObject", setNavigation);
// Clean up when the scope is destroyed // Clean up when the scope is destroyed
$scope.$on("$destroy", function () { $scope.$on("$destroy", function () {
navigationService.removeListener(setNavigation); navigationService.removeListener(setNavigation);
}); });
return {
/**
* Navigate to a specific domain object.
*
* This is exposed so that the browse tree has a callback
* to invoke when the user clicks on a new object to navigate
* to it.
*
* @method
* @memberof BrowseController
* @param {DomainObject} domainObject the object to navigate to
*/
setNavigation: function (domainObject) {
navigationService.setNavigation(domainObject);
}
};
} }
return BrowseController; return BrowseController;

View File

@ -8,9 +8,9 @@
</span> </span>
<mct-representation key="'label'" <mct-representation key="'label'"
mct-object="domainObject" mct-object="domainObject"
parameters="parameters" ng-model="ngModel"
ng-click="parameters.callback(domainObject)" ng-click="ngModel.selectedObject = domainObject"
ng-class="{selected: treeNode.isNavigated()}"> ng-class="{selected: treeNode.isSelected()}">
</mct-representation> </mct-representation>
</span> </span>
<span class="tree-item-subtree" <span class="tree-item-subtree"
@ -18,7 +18,7 @@
ng-if="model.composition !== undefined"> ng-if="model.composition !== undefined">
<mct-representation key="'tree'" <mct-representation key="'tree'"
parameters="parameters" ng-model="ngModel"
mct-object="treeNode.hasBeenExpanded() && domainObject"> mct-object="treeNode.hasBeenExpanded() && domainObject">
</mct-representation> </mct-representation>

View File

@ -1,6 +1,8 @@
<ul class="tree"> <ul class="tree">
<li ng-repeat="child in composition"> <li ng-repeat="child in composition">
<mct-representation key="'tree-node'" mct-object="child" parameters="parameters"> <mct-representation key="'tree-node'"
mct-object="child"
ng-model="ngModel">
</mct-representation> </mct-representation>
</li> </li>
</ul> </ul>

View File

@ -29,9 +29,9 @@ define(
* expand-to-show-navigated-object behavior.) * expand-to-show-navigated-object behavior.)
* @constructor * @constructor
*/ */
function TreeNodeController($scope, navigationService) { function TreeNodeController($scope) {
var navigatedObject = navigationService.getNavigation(), var selectedObject = ($scope.ngModel || {}).selectedObject,
isNavigated = false, isSelected = false,
hasBeenExpanded = false; hasBeenExpanded = false;
// Look up the id for a domain object. A convenience // Look up the id for a domain object. A convenience
@ -73,7 +73,7 @@ define(
// Check if the navigated object is in the subtree of this // Check if the navigated object is in the subtree of this
// node's domain object, by comparing the paths reported // node's domain object, by comparing the paths reported
// by their context capability. // by their context capability.
function isOnNavigationPath(nodeObject, navObject) { function isOnSelectionPath(nodeObject, navObject) {
var nodeContext = nodeObject && var nodeContext = nodeObject &&
nodeObject.getCapability('context'), nodeObject.getCapability('context'),
navContext = navObject && navContext = navObject &&
@ -92,19 +92,19 @@ define(
// Consider the currently-navigated object and update // Consider the currently-navigated object and update
// parameters which support display. // parameters which support display.
function checkNavigation() { function checkSelection() {
var nodeObject = $scope.domainObject; var nodeObject = $scope.domainObject;
// Check if we are the navigated object. Check the parent // Check if we are the navigated object. Check the parent
// as well to make sure we are the same instance of the // as well to make sure we are the same instance of the
// navigated object. // navigated object.
isNavigated = isSelected =
idsEqual(nodeObject, navigatedObject) && idsEqual(nodeObject, selectedObject) &&
idsEqual(parentOf(nodeObject), parentOf(navigatedObject)); idsEqual(parentOf(nodeObject), parentOf(selectedObject));
// Expand if necessary (if the navigated object will // Expand if necessary (if the navigated object will
// be in this node's subtree) // be in this node's subtree)
if (isOnNavigationPath(nodeObject, navigatedObject) && if (isOnSelectionPath(nodeObject, selectedObject) &&
$scope.toggle !== undefined) { $scope.toggle !== undefined) {
$scope.toggle.setState(true); $scope.toggle.setState(true);
hasBeenExpanded = true; hasBeenExpanded = true;
@ -113,17 +113,14 @@ define(
// Callback for the navigation service; track the currently // Callback for the navigation service; track the currently
// navigated object and update display parameters as needed. // navigated object and update display parameters as needed.
function setNavigation(object) { function setSelection(object) {
navigatedObject = object; selectedObject = object;
checkNavigation(); checkSelection();
} }
// Listen for changes which will effect display parameters // Listen for changes which will effect display parameters
navigationService.addListener(setNavigation); $scope.$watch("ngModel.selectedObject", setSelection);
$scope.$on("$destroy", function () { $scope.$watch("domainObject", checkSelection);
navigationService.removeListener(setNavigation);
});
$scope.$watch("domainObject", checkNavigation);
return { return {
/** /**
@ -143,11 +140,13 @@ define(
}, },
/** /**
* Check whether or not the domain object represented by * Check whether or not the domain object represented by
* this tree node is currently the navigated object. * this tree node should be highlighted.
* @returns true if this is the navigated object * An object will be highlighted if it matches
* ngModel.selectedObject
* @returns true if this should be highlighted
*/ */
isNavigated: function () { isSelected: function () {
return isNavigated; return isSelected;
} }
}; };
} }

View File

@ -141,7 +141,12 @@ define(
// Two-way bind key and parameters, get the represented domain // Two-way bind key and parameters, get the represented domain
// object as "mct-object" // object as "mct-object"
scope: { key: "=", domainObject: "=mctObject", parameters: "=" } scope: {
key: "=",
domainObject: "=mctObject",
ngModel: "=",
parameters: "="
}
}; };
} }