-2

There is a functionality where we use nested angular directives. I am adding a simplified example where the behavior can be observed.

Here is the HTML:

<body ng-app="myapp">
    <div>
        This is the first directive
        <first-directive my-val="9">
        </first-directive>
    </div>
</body>

And the JavaScript:

var app = angular.module("myapp",[]);
app.directive("firstDirective",function(){
    return {
            template:'<second-directive val-new={{myVal}}></second-directive>',
            scope:{
                myVal:'@'
            },
            //transclude:true,
            link: {
                pre:function(scope,elem,attr){
                        scope.myVal=scope.myVal+"1";
                    }
            }
    }
});

app.directive("secondDirective",function(){
    return{
        scope:{
            valNew:'@'
        },

        link:{
            pre:function(scope,elem,attr){
                    console.log(scope.valNew);
                }
        }
    }
});

In the console I get the result of the update made in the pre method, but in the html I get the old value.

Console prints: "91" The html dom contains:

    <second-directive val-new="9" class="ng-isolate-scope"></second-directive>>

Please help me understand why this difference is observed and how to make these two places consistent

EDIT I am just looking for a way to make the scope variables in the second directive react to the changes made in the linked variables of the first directive's scope. So in some other place when the myVal changes, I am looking to make the second directive react to the changes.

SamGhatak
  • 1,399
  • 1
  • 13
  • 26
  • I didn't downvote it but I can see that the question is not useful to other readers. Why would any directive need to modify the scope in the preLink function? So why would anyone care about any problems it causes? – georgeawg Dec 06 '18 at 22:46
  • Please don't misunderstand man, you tried to help with the answer as it seems, but since someone else downvoted it, I was just saying the one down voting a post should let the user know the fault he is making, its certainly possible that I am asking a stupid question, but by just downvoting would not help me understand my mistake, right?...actually the situation was complicated, I tried to post a minimal and verifiable reference to the issue. – SamGhatak Dec 10 '18 at 08:11

2 Answers2

0

Move the calculation to the template:

var app = angular.module("myapp",[]);
app.directive("firstDirective",function(){
    return {
            ̶t̶e̶m̶p̶l̶a̶t̶e̶:̶'̶<̶s̶e̶c̶o̶n̶d̶-̶d̶i̶r̶e̶c̶t̶i̶v̶e̶ ̶v̶a̶l̶-̶n̶e̶w̶=̶{̶{̶m̶y̶V̶a̶l̶}̶}̶>̶<̶/̶s̶e̶c̶o̶n̶d̶-̶d̶i̶r̶e̶c̶t̶i̶v̶e̶>̶'̶
            template:'<second-directive val-new="{{myVal+'1'}}"></second-directive>',
            scope:{
                myVal:'@'
            },
            //transclude:true,
            link: {
                pre:function(scope,elem,attr){
                    ̶s̶c̶o̶p̶e̶.̶m̶y̶V̶a̶l̶=̶s̶c̶o̶p̶e̶.̶m̶y̶V̶a̶l̶+̶"̶1̶"̶;̶
                }

            }
    }
});

The attribute ('@') binding creates a watcher that copies the value from the template to the isolate scope every digest cycle. The modification of scope.myVal in the preLink function gets overridden by the watcher on the next digest cycle.

georgeawg
  • 46,994
  • 13
  • 63
  • 85
-1

the problem is that you are passing variables only for values with '@' if you replace it with '=' they will be passed as variable and will be updated

so, change your code in this way

app.directive("firstDirective",function(){
    return {
            template:'<second-directive val-new="myVal"></second-directive>',
            scope:{
                myVal:'='
            },
            //transclude:true,
            link: {
                pre:function(scope,elem,attr){
                        scope.myVal=scope.myVal+"1";
                    }
            }
    }
});

app.directive("secondDirective",function(){
    return{
        scope:{
            valNew:'='
        },

        link:{
            pre:function(scope,elem,attr){
                    console.log(scope.valNew);
                }
        }
    }
});
FarukT
  • 1,150
  • 8
  • 17