mirror of
https://github.com/nasa/openmct.git
synced 2025-02-10 04:41:39 +00:00
[Common UI] Document TreeNodeController
Add in-line documentation to TreeNodeController, and update glossary with some clarifying definition. Additionally, change name from tree-item to tree-node for consistency. Part of ongoing transition of commonUI bundles, WTD-574.
This commit is contained in:
parent
e0b201aa17
commit
2f43e8cd7f
@ -122,8 +122,12 @@ correct usage.)
|
|||||||
* _name_: When used as an object property, this refers to the human-readable
|
* _name_: When used as an object property, this refers to the human-readable
|
||||||
name for a thing. (Most often used in the context of extensions, domain
|
name for a thing. (Most often used in the context of extensions, domain
|
||||||
object models, or other similar application-specific objects.)
|
object models, or other similar application-specific objects.)
|
||||||
|
* _navigation_: Refers to the current state of the application with respect
|
||||||
|
to the user's expressed interest in a specific domain object; e.g. when
|
||||||
|
a user clicks on a domain object in the tree, they are _navigating_ to
|
||||||
|
it, and it is thereafter considered the _navigated_ object (until the
|
||||||
|
user makes another such choice.)
|
||||||
* _space_: A name used to identify a persistence store. Interactions with
|
* _space_: A name used to identify a persistence store. Interactions with
|
||||||
persistence with generally involve a `space` parameter in some form, to
|
persistence with generally involve a `space` parameter in some form, to
|
||||||
distinguish multiple persistence stores from one another (for cases
|
distinguish multiple persistence stores from one another (for cases
|
||||||
where there are multiple valid persistence locations available.)
|
where there are multiple valid persistence locations available.)
|
||||||
|
|
@ -68,8 +68,8 @@
|
|||||||
"templateUrl": "templates/test.html"
|
"templateUrl": "templates/test.html"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "tree-item",
|
"key": "tree-node",
|
||||||
"templateUrl": "templates/tree-item.html",
|
"templateUrl": "templates/tree-node.html",
|
||||||
"uses": [ "action" ]
|
"uses": [ "action" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<ul class="tree">
|
<ul class="tree">
|
||||||
<li ng-repeat="child in composition">
|
<li ng-repeat="child in composition">
|
||||||
<mct-representation key="'tree-item'" mct-object="child" parameters="parameters">
|
<mct-representation key="'tree-node'" mct-object="child" parameters="parameters">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -9,7 +9,24 @@ define(
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The TreeNodeController supports the tree node representation;
|
||||||
|
* a tree node has a label for the current object as well as a
|
||||||
|
* subtree which shows (and is not loaded until) the node is
|
||||||
|
* expanded.
|
||||||
*
|
*
|
||||||
|
* This controller tracks the following, so that the tree node
|
||||||
|
* template may update its state accordingly:
|
||||||
|
*
|
||||||
|
* * Whether or not the tree node has ever been expanded (this
|
||||||
|
* is used to lazily load, exactly once, the subtree)
|
||||||
|
* * Whether or not the node is currently the domain object
|
||||||
|
* of navigation (this gets highlighted differently to
|
||||||
|
* provide the user with visual feedback.)
|
||||||
|
*
|
||||||
|
* Additionally, this controller will automatically trigger
|
||||||
|
* node expansion when this tree node's _subtree_ will contain
|
||||||
|
* the navigated object (recursively, this becomes an
|
||||||
|
* expand-to-show-navigated-object behavior.)
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function TreeNodeController($scope, navigationService) {
|
function TreeNodeController($scope, navigationService) {
|
||||||
@ -17,30 +34,45 @@ define(
|
|||||||
isNavigated = false,
|
isNavigated = false,
|
||||||
hasBeenExpanded = false;
|
hasBeenExpanded = false;
|
||||||
|
|
||||||
function idsEqual(objA, objB) {
|
// Look up the id for a domain object. A convenience
|
||||||
return (objA === objB) ||
|
// for mapping; additionally does some undefined-checking.
|
||||||
(objA && objB && (objA.getId() === objB.getId()));
|
function getId(obj) {
|
||||||
|
return obj && obj.getId && obj.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if two domain objects have the same ID
|
||||||
|
function idsEqual(objA, objB) {
|
||||||
|
return getId(objA) === getId(objB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the parent of a domain object, as reported by
|
||||||
|
// its context capability. This is used to distinguish
|
||||||
|
// two different instances of a domain object that have
|
||||||
|
// been reached in different ways.
|
||||||
function parentOf(domainObject) {
|
function parentOf(domainObject) {
|
||||||
var context = domainObject &&
|
var context = domainObject &&
|
||||||
domainObject.getCapability("context");
|
domainObject.getCapability("context");
|
||||||
return context && context.getParent();
|
return context && context.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getId(obj) {
|
|
||||||
return obj.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that id paths are equivalent, staring at
|
// Verify that id paths are equivalent, staring at
|
||||||
// index, ending at the end of the node path.
|
// index, ending at the end of the node path.
|
||||||
function checkPath(nodePath, navPath, index) {
|
function checkPath(nodePath, navPath, index) {
|
||||||
index = index || 0;
|
index = index || 0;
|
||||||
|
|
||||||
|
// The paths overlap if we have made it past the
|
||||||
|
// end of the node's path; otherwise, check the
|
||||||
|
// id at the current index for equality and perform
|
||||||
|
// a recursive step for subsequent ids in the paths,
|
||||||
|
// until we exceed path length or hit a mismatch.
|
||||||
return (index >= nodePath.length) ||
|
return (index >= nodePath.length) ||
|
||||||
(idsEqual(navPath[index], nodePath[index]) &&
|
(idsEqual(navPath[index], nodePath[index]) &&
|
||||||
checkPath(nodePath, navPath, index + 1));
|
checkPath(nodePath, navPath, index + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the navigated object is in the subtree of this
|
||||||
|
// node's domain object, by comparing the paths reported
|
||||||
|
// by their context capability.
|
||||||
function isOnNavigationPath(nodeObject, navObject) {
|
function isOnNavigationPath(nodeObject, navObject) {
|
||||||
var nodeContext = nodeObject &&
|
var nodeContext = nodeObject &&
|
||||||
nodeObject.getCapability('context'),
|
nodeObject.getCapability('context'),
|
||||||
@ -58,14 +90,20 @@ define(
|
|||||||
return false; // No context to judge by
|
return false; // No context to judge by
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consider the currently-navigated object and update
|
||||||
|
// parameters which support display.
|
||||||
function checkNavigation() {
|
function checkNavigation() {
|
||||||
var nodeObject = $scope.domainObject;
|
var nodeObject = $scope.domainObject;
|
||||||
|
|
||||||
|
// Check if we are the navigated object. Check the parent
|
||||||
|
// as well to make sure we are the same instance of the
|
||||||
|
// navigated object.
|
||||||
isNavigated =
|
isNavigated =
|
||||||
idsEqual(nodeObject, navigatedObject) &&
|
idsEqual(nodeObject, navigatedObject) &&
|
||||||
idsEqual(parentOf(nodeObject), parentOf(navigatedObject));
|
idsEqual(parentOf(nodeObject), parentOf(navigatedObject));
|
||||||
|
|
||||||
// Expand if necessary
|
// Expand if necessary (if the navigated object will
|
||||||
|
// be in this node's subtree)
|
||||||
if (isOnNavigationPath(nodeObject, navigatedObject) &&
|
if (isOnNavigationPath(nodeObject, navigatedObject) &&
|
||||||
$scope.toggle !== undefined) {
|
$scope.toggle !== undefined) {
|
||||||
$scope.toggle.setState(true);
|
$scope.toggle.setState(true);
|
||||||
@ -73,11 +111,14 @@ define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Callback for the navigation service; track the currently
|
||||||
|
// navigated object and update display parameters as needed.
|
||||||
function setNavigation(object) {
|
function setNavigation(object) {
|
||||||
navigatedObject = object;
|
navigatedObject = object;
|
||||||
checkNavigation();
|
checkNavigation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Listen for changes which will effect display parameters
|
||||||
navigationService.addListener(setNavigation);
|
navigationService.addListener(setNavigation);
|
||||||
$scope.$on("$destroy", function () {
|
$scope.$on("$destroy", function () {
|
||||||
navigationService.removeListener(setNavigation);
|
navigationService.removeListener(setNavigation);
|
||||||
@ -85,12 +126,26 @@ define(
|
|||||||
$scope.$watch("domainObject", checkNavigation);
|
$scope.$watch("domainObject", checkNavigation);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
/**
|
||||||
|
* This method should be called when a node is expanded
|
||||||
|
* to record that this has occurred, to support one-time
|
||||||
|
* lazy loading of the node's subtree.
|
||||||
|
*/
|
||||||
trackExpansion: function () {
|
trackExpansion: function () {
|
||||||
hasBeenExpanded = true;
|
hasBeenExpanded = true;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Check if this not has ever been expanded.
|
||||||
|
* @returns true if it has been expanded
|
||||||
|
*/
|
||||||
hasBeenExpanded: function () {
|
hasBeenExpanded: function () {
|
||||||
return hasBeenExpanded;
|
return hasBeenExpanded;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Check whether or not the domain object represented by
|
||||||
|
* this tree node is currently the navigated object.
|
||||||
|
* @returns true if this is the navigated object
|
||||||
|
*/
|
||||||
isNavigated: function () {
|
isNavigated: function () {
|
||||||
return isNavigated;
|
return isNavigated;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user