Q:

AngularJS - How to pass data through nested (custom) directives from child to parent

I am looking to find the best way of sending scope through nested directives.
I have found that you can do $scope.$parent.value, but I understood that's not a best practice and should be avoided. 
So my question is, if I have 4 nested directives like below, each with it's own controller where some data is being modified, what's the best way to access a value from directive4 (let's say $scope.valueFromDirective4) in directive1?  
<directive1>
    <directive2>
        <directive3>
            <directive4>
            </directive4>
        </directive3>
    </directive2>
</directive1>

A:

For the "presentational" / "dumb" components (directive3 and directive4), I think they should each take in a callback function which they can invoke with new data when they change:
scope: {
    // Invoke this with new data
    onChange: '&',
    // Optional if you want to bind the data yourself and then call `onChange`
    data: '='
}

Just pass the callback down from directive2 through directive4. This way directive3 and directive4 are decoupled from your app and reusable. 
If they are form-like directives (similar to input etc), another option is to look into having them require ngModel and have them use ngModelController to update the parent and view. (Look up $render and $setViewValue for more info on this). This way you can use them like:
<directive4 ng-model="someObj.someProp" ng-change="someFunc()"></directive4>

When you do it like this, after the model is updated the ng-change function is automatically invoked.
For the "container" / "smart" directives (directive1 and directive2), you could also have directive2 take in the callback which is passed in from directive1. But since directive1 and directive2 can both know about your app, you could write a service which is injected and shared between directive1 and directive2.

