We're going through something similar on our end.
One important concept that took us some time to wrap our heads around was that all components have isolate $scope. So in theory this prevents the '$scope soup' problem you mentioned, but in practice this leads to the need to explicitly pass data into and out of components which can take some getting used to.
In general, you'll want to keep your data immutable, that is, prevent child components from changing data directly (except in some specific cases where two-way data binding improves UI).
The idea here is to pass data into components using one-way data binding like this:
...
bindings: {
oneWayBindingInput: '<'
},
...
and then pass events back out of child components to then be handled by the parent:
...
bindings: {
oneWayBindingInput: '<'
onEventOutput: '&'
},
...
So in your case, you might try something like this:
Component tag (in parent template):
<section-dates dates="dates" on-update="handleUpdateEvent($event)"></section-dates>
Component:
app.component("sectionDates", {
bindings: {
dates: "<",
onUpdate: "&"
},
controller: function () {
this.onClickADate = function (date)
{
this.onUpdate({$event: {date: date});
}
...
}
Parent Controller:
app.controller('ParentCtrl', function ($scope) {
$scope.dates = [...array of dates...];
$scope.handleUpdateEvent = function(event) {
$scope.date = event.date;
};
})
Just a quick note. If the data you one-way data bind into the component is an object, it's properties will still be mutable. One-way data binding is not broken here, this is typical javascript behavior. Todd Motto discusses a great technique to overcome this by cloning the data to break the binding:
$onChanges() = function(changes) {
if(changes.user) {
this.user = angular.copy(this.user);
}
};
For more examples see these references with useful component patterns:
https://toddmotto.com/exploring-the-angular-1-5-component-method/
http://dfsq.info/site/read/angular-components-communication