Q: How to know when the ngModel of a select refers to an unknown option in ngOptions I have two cascading drop downs based on a common dataset "options". The first selected value filter the options available in the second select. 
<label for="select1" class="control-label">Select1</label>
<select name="select1" ng-model="select1" ng-options="option.select1 as option.select1 for option in options | unique: 'select1' | orderBy: 'select1'">
</select>

<label for="select2" class="control-label">Select2</label>
<select name="select2" ng-model="select2" ng-options="option.select2 as option.select2 for option in options | filter: {select1: select1} | unique: 'select2' | orderBy: 'select2'">
</select>

When the user change the value in select1, the value already selected in select2 might or might not still be available. When the value becomes unknown in select2, angular reflect this by selecting the unknown ("?") val in the select but it doesn't change the model. 
The problem is that I don't know how to figure out when an invalid value has been selected. I would like to set it to null or at least know that the value is invalid.
I put an example of this behavior in a jsfiddle
I tried to create a directive that listen to view value change and changing the model to null when "?" is selected but the change event is not fired when angular set the view to the unknown value.
.directive('known', function() {
    return {
        restrict: 'AC',
        require: ['select', '?ngModel'],
        link: function ($scope, $element, $attrs, ctrls) {

            $element.change(ctrls, function() {
                if ($element.val() == "?")
                    ctrls[1].$setViewValue(null);
            });
        }
    };
 })

Thanks for your time
Edit:
I might over simplify my problem: there are usually 5 cascading selects bound to each other. Select(n+2) depends on select(n+1) and select(n). Select(n) is not aware of selects depending on him, eg of select(n+1, n+2, ...). The form is dynamically generated based on a form view model created by a super user (something similar to https://github.com/Selmanh/angularjs-form-builder). 
So in my use case, it might be easier if I can figure out if the value is invalid from the select2 point of view.

A: Use ng-change on the first drop down:
<label for="select1" class="control-label">Select1</label>
<select name="select1" ng-model="select1" ng-options="option.select1 as option.select1 for option in options | unique: 'select1' | orderBy: 'select1'" ng-change="select1Changed()">
</select>

<label for="select2" class="control-label">Select2</label>
<select name="select2" ng-model="select2" ng-options="option.select2 as option.select2 for option in options | filter: {select1: select1} | unique: 'select2' | orderBy: 'select2'">
</select>

in your controller:
$scope.select1Changed = function () {
   // logic of known/unknown based on $scope.select1
}

Hope this helps.

A: I finally created a validation directive watching for DOM, model and options collection changes. When the collection is modified, I check if the value "?" has been selected in the view and consider the value unknown if it did.
It is generic enough for my use case, but still missing handling things like "tracked by" or multiple selection to fit all cases. Anyway, thought that might help someone:
.directive('known', ['$parse', function($parse) {

var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;

return {
    restrict: 'AC',
    require: ['select', '?ngModel'],
    link: function ($scope, $element, $attrs, ctrls) {
        var optionsExp = $attrs.ngOptions,
            modelCtrl = ctrls[1];
        if (match = optionsExp.match(NG_OPTIONS_REGEXP)) {
            var valueName = match[4] || match[6],
                keyName = match[5],
                valueFn = $parse(match[2] ? match[1] : valueName),
                valuesFn = $parse(match[7]);

            $scope.$watchCollection(valuesFn, function() {
                modelCtrl.$setValidity('unknown', !($element.val() == "?" && modelCtrl.$viewValue));
            });

            modelCtrl.$parsers.unshift(function(value) {
                // value set from view can only be a known one
                 modelCtrl.$setValidity('unknown', true);
                 return value;
            });

            modelCtrl.$formatters.unshift(function(value) {
                var values = valuesFn($scope) || [];
                var valid = false;

                for (var i = 0; i < values.length; i++) {
                    var local = {};
                    local[valueName] = values[i];
                    if (value === valueFn(local)) {
                        valid = true;
                        break;
                    }
                }

                modelCtrl.$setValidity('unknown', valid);
                return value;
            });
        }
    }
};
}]);

jsfiddle
