1

I have an Angular JS directive that looks something like this:

function ($sce) {
    'use strict';

    return {
        restrict: 'E',
        templateUrl: $sce.trustAsResourceUrl('...'),
        scope: {
            serviceName: '@?',
        },
        controller: 'MyController',
        link: function () {}
    };
}

The directive is instantiated like so:

<my-directive service="My Cool Service"></my-directive>

Recently, some consumers of this directive would like the ability to modify the service attribute after the directive has been instantiated and have the directive reflect the change. Here is an example of what a specific consumer is doing:

const directive = document.querySelector('my-directive');
directive.setAttribute('service', 'Another Service Name');

This makes sense; however, the directive does not reflect the change once they set the attribute. I am figuring out a way to accomplish this. I have tried using scope.$watch and $observe to no avail; example:

link: function (_, _, attrs) {
    attrs.$observe("serviceName", newValue => updateServiceName(newValue));
}

Any insights on how to accomplish this? Thanks!

rafa
  • 47
  • 8

1 Answers1

0

The serviceName property inside your directive's scope definition should be bound with = instead of @. Then, from the outer code, just pass in the service name with a variable.

$scope.myServiceName = "My Cool Service";
<my-directive service="{{myServiceName}}"></my-directive>

Now if you change the myServiceName value, the change will be reflected in the child directive.

Jacob Stamm
  • 1,660
  • 1
  • 29
  • 53
  • This directive is consumed by other UIs, written in different frameworks, and by other teams. So I need to be able to select the element and manually update the attribute and have the directive re-render based on that change. Would the same advice apply? – rafa Feb 16 '23 at 19:26