0

I have a directive twice on a page, but it keeps overwriting itself. Meaning, the dialogId gets overwritten by the next instance of example-dialog in the template instead of keeping their own dialogIds.

angular.module('directives')
    .directive('exampleDialog', ["$rootScope", "$timeout", "ngDialog", "$compile", '$templateRequest', function ($rootScope, $timeout, ngDialog, $compile, $templateRequest) {
        return {
            templateUrl: "/dialog.component.html",
            transclude: {
                button: '?dialogButton',
                title: '?dialogTitle',
                body: '?dialogBody',
                footer: '?dialogFooter'
            },
            replace: true,
            link: function (scope, el, attrs, ctrl, transclude) {
                var dialogId = scope.blah.id; // gets overwritten - so when scope.open() gets called, the last instance ID gets used for both

                scope.open = function(){
                    console.log(dialogId) // prints the same for both directives instead of the unique dialogId.
                }
            },
            controller: function ($scope) {

            }
        }
    }]);

With the following HTML:

<example-dialog>
    <dialog-button>
        <a href="#" ng-click="open()">ExampleButton1</a>
    </dialog-button>
    <dialog-title ng-non-bindable>Title1</dialog-title>
    <dialog-body ng-non-bindable>
        <div ng-include="'template1.tpl.html'"></div>
    </dialog-body>
    <dialog-footer ng-non-bindable>
    </dialog-footer>
</example-dialog>


<example-dialog>
    <dialog-button>
        <a href="#" ng-click="open()">ExampleButton2</a>
    </dialog-button>
    <dialog-title ng-non-bindable>Title2</dialog-title>
    <dialog-body ng-non-bindable>
        <div ng-include="'template2.tpl.html'"></div>
    </dialog-body>
    <dialog-footer ng-non-bindable>
    </dialog-footer>
</example-dialog>

How can I get them to save their own references while still inheriting their parents' scope?

EDIT Someone recommended that I use scope: true which is supposed to create classic prototypal inheritance.

However, When I try that - open() from the <dialog-button> tansclusion point doesn't work now, along with any other bindings in the template.

itamar
  • 3,837
  • 5
  • 35
  • 60

2 Answers2

0

You should isolate the scope of your directive. by adding scope:{} in your return statement.

By doing this your directive will create its own controlled scope and you will not be able to get any value from your parent scope(Basically no conflicts from parent scope).. To access value from parent controller/scope you will need to pass them explicitly.

Ashwani Kumar
  • 216
  • 2
  • 14
0

To complet the previous answer, you can see in angular official doc ( here ) that :

The scope property can be false, true, or an object:

false (default): No scope will be created for the directive. The directive will use its parent's scope.

true: A new child scope that prototypically inherits from its parent will be created for the directive's element. If multiple directives on the same element request a new scope, only one new scope is created.

{...} (an object hash): A new "isolate" scope is created for the directive's template. The 'isolate' scope differs from normal scope in that it does not prototypically inherit from its parent scope. This is useful when creating reusable components, which should not accidentally read or modify data in the parent scope. Note that an isolate scope directive without a template or templateUrl will not apply the isolate scope to its children elements.


Edit Like @itamar mentioned in his comment :

When I use scope:true it seems that it does keep the id in the directive (checked with going to the dom element and printing the scope). However, open() from the tansclusion point doesn't work now, along with any other bindings in the template.

The answer (from angularjs doc ) is :

The 'isolate' scope object hash defines a set of local scope properties derived from attributes on the directive's element. These local properties are useful for aliasing values for templates. The keys in the object hash map to the name of the property on the isolate scope; the values define how the property is bound to the parent scope, via matching attributes on the directive's element:

  • @ or @attr - bind a local scope property to the value of DOM attribute.
  • = or =attr - set up a bidirectional binding between a local scope property and an expression passed via the attribute attr. The expression is evaluated in the context of the parent scope.
  • < or < attr - set up a one-way (one-directional) binding between a local scope property and an expression passed via the attribute attr. The expression is evaluated in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name.
  • & or &attr - provides a way to execute an expression in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name.
Abdelghani Roussi
  • 2,707
  • 2
  • 21
  • 39
  • Okay - the problem is, if I use scope with &, I lose the advantage of inheriting from the parent, no? – itamar Jun 11 '17 at 12:51