0

In my angular js Application, I have a directive inside a ng-repeat. Directive has a template in which the HTML part is loaded. Inside that template I am declaring a ui-sref Router dynamically setting states!

This does not Work!

I have tried a Fiddle

Without using a Directive ui-sref works Fine. But I need it in Directive's template.

MY HTML PART

<div ng-repeat="sp in obj.PEs">
  <div draw-pe proc="{{sp.peId}}"></div>
</div>

<div style="border:1px;" ui-view="properties"></div>

My Script Part

var myApp = angular.module('myApp', ["ui.router"]);
myApp.controller("testCtrl", function($scope) {
  $scope.obj = {
    "PEs": {
      "1": {
        "peId": "1",
        "peName": "Exp1",
        "peDisplayName": "Exp",
        "peType": "Exp",
        "peCategory": "PE"
      },
      "2": {
        "peId": "2",
        "peName": "RN1",
        "peDisplayName": "RNull",
        "peType": "RN",
        "peCategory": "PE"
      }
    }
  }
})

myApp.config(function($stateProvider, $urlRouterProvider) {
  $urlRouterProvider.otherwise('/');
  $stateProvider
    .state('Exp', {
      url: '/Exp/:peId',
      views: {
        "properties": {
          template: ".<h3>I am Exp ! </h3>",
          controller: function($scope, $stateParams) {
            var peId = $stateParams.peId;
            alert("Peid-> " + angular.toJson($scope.obj.PEs[peId]));

          }
        }
      }
    })
    .state('RN', {
      url: '/RN/:peId',
      views: {
        "properties": {
          template: "<h3> I am RN ! </h3>",
          controller: function($scope, $stateParams) {
            var peId = $stateParams.peId;
            alert("Peid-> " + angular.toJson($scope.obj.PEs[peId]));
          }
        }
      }
    })
});
myApp.directive("drawPe", function() {
  return {
    restrict: "AE",
    template: '<div ui-sref="{{peObj.peType}}( { peId:peObj.peId } )"> <h5>{{peObj.peDisplayName}}</h5></div>',
    link: function($scope, element, attrs) {
      var procId = $scope.$eval(attrs.proc);
      alert(procId);
      // alert(angular.toJson(scope.obj.processElements[procId]))
      $scope.peObj = $scope.obj.PEs[procId];
    }
  }
})

See the Browser Console, on clicking the output Part!

ERROR

Error: Invalid state ref '( { peId:peObj.peId } )'

What will be the best Practice to call dynamic state names inside directives Template? I Have read some previous asked question and answer, But I am not clear with the idea as I am new to Angular Js.

Any Idea/help appreciated

Thanks

1

1 Answer 1

2

You can use $compile service to compile your directive's template when your scope changes.

Your directive could look like this:

myApp.directive("drawPe", function($compile) {

return {
 restrict: "AE",
 tranclude: true,
 scope: {
   peObj: '='
 },
 template: '<a href="" ui-sref="{{peObj.peType}} ({peId: peObj.peId})"> <h5>{{peObj.peDisplayName}}</h5></a>',
 link: function(scope, element, attrs) {
  console.log(scope.peObj);
  scope.$watch(
    function(scope) {
      // watch the 'compile' expression for changes
      //return scope.$eval(attrs.compile);
    },
    function(value) {
      $compile(element.contents())(scope);
    }
  );
  }
 }
 });

And your html:

<div ng-repeat="sp in obj.PEs">
  <div draw-pe pe-obj="sp" proc="{{sp.peId}}"></div>
</div>

<div style="border:1px;" ui-view="properties"></div>

Working fiddle is here.

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

5 Comments

I need to bind the rootscope obj in peObj in link, I couldn't able to access obj, because the scope is changed? what should we do to make obj variable accessible in link function? console.log(scope.obj); -> this gives undefined
You can assign your 'obj' variable to $rootScope instead of $scope. Then use it in directive like: myApp.directive("drawPe", function($rootScope) { return { link: function(...) { console.log($rootScope.obj) } });
Actually It is working in fiddle but not in my application. My rootScope variable not accessible in drawPe directive. getting undefined.
Did you define $rootScope in your controller as dependency? Your controller should start like: myApp.controller("testCtrl", function($rootScope) { $rootScope.obj = {.....
Thank you for your Wonderful help ! But without $watch only if we compile $compile(element.contents())(scope); my problem got solved! Thanks man !

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.