A directive allowing to make a whole DOM subtree readonly
Generally speaking, you should avoid looking outside the current directive for anything that would affect your internal state (bar events). The preferred method of communication is scopes. Here is how I would recommend you do this.

&lt;div ng-controller="MyCtrl"&gt;
    &lt;div&gt;
        &lt;input ng-readonly="is_readonly" /&gt;
    &lt;/div&gt;
    &lt;div&gt;
        &lt;div&gt;
            &lt;input ng-readonly="is_readonly" /&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


Simply toggling $scope.is_readonly from MyCtrl is enough to disable all child inputs that have ng-readonly="is_readonly", and it's bindable too, so you can add/remove readonly status at runtime.

Now, if there is a genuine need to have the behaviour you described, then you have 2 options.


Stick with your current implementation, but this will not be performant, since your DOM traversal will fire any time the scope changes, for any reason, anywhere up the scope tree.
Rewrite to use directive's require property.


Here is how you would do the latter.

.directive("readonly", function() {
    return {
        restrict: "C",
        link: function() {},
        controller: function() {},
    }
})
.directive("input", function()
    return {
        restrict: "E",
        // search for optional parent directive named `readonly`
        require: "^?readonly",
        // 4th parameter is `readonly` controller or null.
        link: function($scope, element, attr, has_readonly) {
            var org = attr.ngReadonly;
            if (org) {
                return; // readonly seems to be set manually, so let's not touch it
            } else if (has_readonly) {
                attr.$set("readonly", true)
            }
        },
    };
})


This tells angular that it should pass you a reference to the readonly controller if found, or null otherwise. In this way, you can tell at link time whether the parent node exists. This saves you from performing the DOM traversal yourself, and should be faster too.

Again, I highly recommend that you simply bind to a scope variable instead of checking for the presence of a class further up the tree.