Q: I need parent <---> child directive communication within a table with sibling rows I am needing to develop a table that uses some more complex UI operations than a typical table.  At first glance there could be 1 single row, then when clicked on, the row "expands" and 3 more rows appear below it.  From a data-model point of view, these 3 rows are children of the parent (Parent row displays Order information, child rows display individual product info), but in the DOM these 4 rows are all seperate siblings.
Since they are siblings in the DOM, it makes it hard to write an Angular directive using the require attribute to communicate with the parent controller API.  I also cannot wrap my <tr>'s in a parent element that I use as the API because HTML5 standards don't let us do something like
<table>
    <tbody>
        <div my-parent-directive>
            <tr my-order-row></tr>
            <tr my-product-row></tr>
            <tr my-product-row></tr>
            <tr my-product-row></tr>
        </div>
    </tbody>
</table>

This goes against proper HTML structure, therefore I have no idea how I can get this functionality using directives that communicate to one another.  Any ideas?

A: well, you can pass the same bound object into each directive (the parent and children) and then watch for changes on the object in each directive and take the appropriate action. 
<table>
 <tbody>
   <div my-parent-directive shared-attribute="someAttribute">
     <tr my-order-row   shared-attribute="someAttribute"></tr>
     <tr my-product-row shared-attribute="someAttribute"></tr>
     <tr my-product-row shared-attribute="someAttribute"></tr>
     <tr my-product-row shared-attribute="someAttribute"></tr>
   </div>
 </tbody>
</table>

Assuming that you declare the object in $scope of the controller the directive is housed in.
$scope.someAttribute = {sharedData: 7, today: new Date(), etc... };

In each of your directives you will need to make sure that the attribute is two way data-bound (or at least in the directives that will be making modifications.
angular.module('myModule').directive('myDirective', ['$filter', // inject dependencies
    function($filter) {
        return {
            restrict: 'A', 
            scope: {
                sharedAttribute: '=', // in HTML this will be shared-attribute="someObject" , "=" means two way data binding, "@" would mean one way binding... essentially a string, "&" would mean you want to pass a function name. etc...
            },
            link: function(scope, elem, attrs) { 


                 scope.$watch('sharedAttribute', function(newValue, oldValue){
                     // do something when object changes
                     // you could change the above to 'sharedAttribute.someProperty' to watch a property of the object
                     console.log('sharedAttribute chaged', sharedAttribute);
                 });
            }
        }
     }
 });

Update
Regarding your concerns, you can communicate a simple boolean for showing child rows as such:
<table>
 <tbody>
   <div my-parent-directive shared-attribute="someObject" ng-click='someObject.showChildren=!someObject.showChildren'>
     <tr my-order-row   shared-attribute="someObject" ng-show="someObject.showChildren"></tr>
     <tr my-product-row shared-attribute="someObject" ng-show="someObject.showChildren"></tr>
     <tr my-product-row shared-attribute="someObject" ng-show="someObject.showChildren"></tr>
     <tr my-product-row shared-attribute="someObject" ng-show="someObject.showChildren"></tr>
   </div>
 </tbody>
</table>

The shared object controls visibility of children via ng-show, or you could use ng-class as well. 
I don't know what exactly you're trying to achieve, but this would completely address the directives being able to communicate with each other. 
The great thing here is that once you modify the value in one directive, it will be changed in all the other directives that share that value.
Also, don't feel that it's "wrong" to put a isDroppedDown boolean on each of the JSON objects in the Array in the table; this is actually a "good" thing. It's called pre-processing, meaning that you would want to process the object first and then make it available in scope, then angular doesn't have to muck around with the details, it just processes the display of the object. And when you make changes to the object, it will update the view live.
You may feel this is a bit 'memory intensive' adding attributes to multiple objects (especially those in a repeater), but this is a good way to do things as you can keep track of object state through the flow of the application.
