简体   繁体   中英

How to access controller scope from dynamically created directive

Basically I am trying to access controller scope property from directive's controller function. I am doing it through $parent property. It works fine for static directive but not for dynamically created directive. please have a look on my plunker

Dynamic Directive

In a plunker, when I click on folder with Id = 1. all goes good and folder path shows as "1 path". Same goes for folder with Id = 2. But it does not work for dynamically appended folder with Id = n

I am somewhat new to angular. Any help would be much appreciated.

Updated Answer

In light of the latest requirement:

I am trying to call the directive function (ie updateMap) from controller.

You can use a Service to share variables between Controllers and Isolated Directives . In the example below, the Service holds the function that will be executed. Each directive when clicked will set the Service's function to it's own updateMap() function. Then the Controller in onFolderPathClicked() calls the Services executeFunction() function, which runs the previously set function.

script.js:

var module = angular.module('testApp', []);

module.service('updateMapService', function(){
  var updateMapFunction = null;
  this.executeFunction = function(){
    updateMapFunction();
  };
  this.setFunction = function(fn){
    updateMapFunction = fn;
  };
});
module.controller('crtl', function($scope, updateMapService) {
  $scope.onFolderPathClicked = function(){
    updateMapService.executeFunction();
  };
});
module.directive('folder', function($compile) {
  return {
    restrict: 'E',
    scope: {
      id: '@',
      folderPath: "="
    },
    template: '<p ng-click="onFolderClicked()">{{id}}</p>',
    controller: function($scope, $element, updateMapService) {
      $scope.onFolderClicked = function(){
        updateMapService.setFunction(updateMap);
        addFolder();
      };
      var addFolder = function() {
        $scope.folderPath = $scope.id + ":click here for calling update map";
        var el = $compile('<folder id="n" folder-path="folderPath"></folder>')($scope);
        $element.parent().append(el);
      };
      var updateMap = function() {
        alert('inside updateMap()..' + $scope.id);
      }
    }
  }
});

index.html:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="style.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
<body>
  <div ng-app="testApp" ng-controller="crtl">
    <div>FolderPath : <a ng-click="onFolderPathClicked()">{{ folderPath }}</a> </div>
    <folder id="1" folder-path="folderPath"></folder>
    <folder id="2" folder-path="folderPath"></folder>
  </div>
</html>

You could also move folder-path into a Service to save from passing it in as an attribute. The code smell being that passing it in as an attribute means doing so twice, whereas in a Service it means setting it and getting it once (code reuse).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM