2

I have a strange problem with angular directive.

Here is a detailed description of the facts, embedded within my (2) questions.

I have two directives drtv-a and drtv-b. drtv-a uses within in it's template drtv-b

drtv-a template:

<drtv-b some-attribute="something"></drtv-b>

here is how I use drtv-a in another piece of html element:

<drtv-a some-other-attribute="other something"></drtv-a>

drtv-a is defined with replace:true. In it's controller I hang $scope.something ={...}

drtv-b is defined with scope:true, and once used he is verifying and validating the owner scope indeed has the 'something' on it.

The problem:

The validating code of drtv-b is executed BEFORE drtv-a controller get's to be executed. This leads to a problem where the validation of drtv-b fails my application (as the property 'something' can not be found).

After long investigation, it appeared that the problem was at the drtv-a definition, at the replace:true definition !

The replace:true makes the html of the template using drtv-a look something like that:

<drtv-b some-attribute="something" some-other-attribute="other something"></drtv-b>

Though it is what I expected the replace:true to do (according to it's docs), it has also (unexpectedly) changed the order of execution of the angular constructs: the inner directive code (drtv-b) now runs BEFORE the outer directive (drtv-a) controller had the chance to properly initiate. This is off course un-(wanted + expected + DOCUMENTED) behavior.

My first question: why does it happen ? is it a bug or something that I fail to understand ?

Then, I have discovered even stranger issue:

if I change the template of drtv-a to be contained within a <div> element:

<div>
    <drtv-b some-attribute="something"></drtv-b>
</div>

and return the replace:true definition to drtv-a, then after angular performs the replacements, the html code now looks like that:

<div some-other-attribute="other something">
    <drtv-b some-attribute="something"></drtv-b>
</div>

and it runs OK !

(that is: the drtv-a controller code runs before the drtv-b code that uses it.)

My second question: why simply having the code wrapped with a container element solve the problem ? isn't that weak and so-not-robust behavior of the framework ?

aviad cohen
  • 637
  • 1
  • 6
  • 16

1 Answers1

0

I'm sorry, I cannot offer you a solution other than nesting or replace: false.

Mainly due to issues similar to yours, replace is now deprecated: See the doumentation. More background information and issues regarding replace: true: GitHub commit, GitHub issue and Why is replace deprecated in AngularJS?

From the GitHub issue:

[...] you aren't going to see replace disappear from angular 1.x (I don't know this for sure, but I'm fairly sure we won't be removing it, since it's a huge breaking change. It's deprecated, that's all).

It's deprecated because there are known, very silly problems with replace: true, a number of which can't really be fixed in a reasonable fashion. If you're careful and avoid these problems, then more power to you, but for the benefit of new users, it's easier to just tell them "this will give you a headache, don't do it".

Community
  • 1
  • 1
Blaise
  • 13,139
  • 9
  • 69
  • 97