0

I need to take a step back and understand the data flow between controllers to directive, directive to controller and the inline template vs template url in directives.

I have customDirective created with both inline template as well templateUrl for testing purpose. I have attached few values to scope in controller ( obj.prop= "Germany", name.firstname= "Gotze", originalBill="$20" ) and will change the values in directive and add one more ( obj.prop= "USA", name.firstname= "Tom", originalBill= not changed, bill="4000", applyTest="New Value" ). So i expect inline or url template to display values from directive and retain the unchanged values from the controller.

index

<pass-object obj="obj" name="name" bill="bill" originalBill="originalBill" applyTest="applyTest"></pass-object>

customDirective

app.directive('passObject', function() {
return {
    restrict: 'AE',
    scope: { 
      obj: '=',
      name:'=',
      bill:'=',
      applyTest:'='
    },
   templateUrl:'./customDirective.html',
  /* template: `<div style="color:brown">
              =====Directive Inline Template===== <br/>
              Country Name : {{obj.prop}}! <br/>
              Person Name: {{name.firstname}} <br/>
              Original money : {{originalBill}} <br/>
              Bill Money: {{bill}} <br/>
              Testing Apply: {{applyTest}} <br/>
              Two Way Binding: <input type="text" ng-model="obj.prop" ng-model="name.firstname"/>
              </div>`,
    */
    link: function(scope, element, attrs){
      scope.name = { firstname: "Tom" };
      scope.obj = { prop: "USA" };
      scope.bill="$4000";

      scope.$apply(function() {
        scope.applyTest= " New Value";
      });
    }
};
});

Problem/Confusion ( check plunker ):
1. when you use templateUrl, why didn't obj.prop, name.firstname change from directive but the values in index page changed from directive ?
2. when you use inline template both in index and inline html reflects right values from directive for obj.prop, name.firstname; but originalBill doesn't get the value ?
3. Why can't i retrieve applyTest value from scope?

Plunker

2 Answers 2

1

Attribute names need to be in kebab-case, not camelCase:

<!-- ERRONEOUS
<pass-object obj="obj" name="name" bill="bill" 
             originalBill="originalBill" applyTest="applyTest">
</pass-object>
-->

<!-- CORRECT -->
<pass-object obj="obj" name="name" bill="bill" 
             original-bill="originalBill" apply-test="applyTest">
</pass-object>

For more information, see AngularJS Developer Guide - Directive Normalization


Also don't do $apply in a linking function:

link: function(scope, element, attrs){
  scope.name = { firstname: "Tom" };
  scope.obj = { prop: "USA" };
  scope.bill="$4000";

  //DONT use $apply here
  //scope.$apply(function() {
    scope.applyTest= "New Value";
  //});
}

At any point in time there can be only one $digest or $apply operation in progress. This is to prevent very hard to detect bugs from entering your application.

This error can be seen in the debug console.

For more information, see AngularJS Error Reference - $rootScope:inprog

Sign up to request clarification or add additional context in comments.

Comments

1
  1. when you use templateUrl, why didn't obj.prop, name.firstname change from directive but the values in index page changed from directive ?

    Answer: because you have used controller 'MainCtrl' in html file 'customDirective.html' as

  2. when you use inline template both in index and inline html reflects right values from directive for obj.prop, name.firstname; but originalBill doesn't get the value ?

    Answer: Because you didn't mention scope originalBill:'=' in directive.

  3. Why can't i retrieve applyTest value from scope?

    answer: You have to correct name as apply-test="applyTest" instead of applyTest="applyTest"

You can check working code here.

customDirective.html

    <div>
      <h4 style="color:blue"> ** Custom Directive ** </h4>
      <table style="width:50%">
      <tr>
        <th>Country</th>
        <th>Person</th>
        <th>Money</th>
        <th>Original Money</th>
        <th>Testing Apply </th>
      </tr>
      <tr>
        <td>{{obj.prop}}</td>
        <td>{{name.firstname}}</td>
        <td>{{bill}}</td>
        <td>{{originalBill}}</td>
        <td>{{applyTest}} </td>
      </tr>
    </table>
    </div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.