0

I have a simple directive with transcluded html. I want to be able to inject directive scope params to the transclude. I wrote a simple example in plunker : https://plnkr.co/edit/jqyiQdgQxbeTrzyidZYF?p=preview

I know in angular 4 it can be done, but I can't find a good way to do it in angularjs.

// Code goes here

var app = angular.module("app", []);

app.controller("mainCtrl", function($scope) {
  $scope.users = ["tal", "oren", "orel", "shluki"];
  
  $scope.deleteUser = (user) => {alert("trying to delete", user);}
});

app.directive('myList', function myList() {
    return {
        restrict: 'E',
        transclude: true,  
        template: "<div><table><tr ng-repeat='item in collection'><td> This is inside myList - user name: {{item}} <ng-transclude></ng-transclude></td></tr></table></div>",
        scope: {
          collection: "="
        },
        replace: true
    };
});
<!DOCTYPE html>
<html>

  <head>
    <script data-require="angularjs@1.6.2" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-app="app" ng-controller="mainCtrl">
      <h1>Hello Plunker!</h1>
      <my-list collection="users">
         <h2>This is transclude</h2>
         <button ng-click="deleteUser(user)">Delete user: {{user ? user : "User name should be here"}}</button>
      </my-list>
  </body>

</html>

Will really appreicate some help.

plunker: https://plnkr.co/edit/jqyiQdgQxbeTrzyidZYF?p=preview

Tal Humy
  • 1,197
  • 1
  • 18
  • 41

1 Answers1

0

Here's a working plunker with your example. http://plnkr.co/edit/BjSowyQdLXd0xoCZFqZ6?p=preview

The idea is to pass it as contents and not html as string. $compile is here because the link is done after ng-repeats already has transcluded its own template.

var template = '<h1>I am foo</h1>\
                  <div ng-repeat="item in users">\
                    <placeholder></placeholder>\
                    <hr>\
                  </div>';
  var templateEl = angular.element(template);

  transclude(scope, function(clonedContent) {
    templateEl.find("placeholder").replaceWith(clonedContent);

    $compile(templateEl)(scope, function(clonedTemplate) {
      element.append(clonedTemplate);
    });
  });

If you want a proper explanation of what the problem was you should check the detailed answer here : Pass data to transcluded element

Hope this helped you out

  • First of all, thank you very much for your help. I tought about it at first, but the only issue with this is that I loose the container scope. If I try to access some data from the main page, I can't do it anymore. you solution implemented on my example will not call deleteUser function, since the scope was replaced. – Tal Humy Aug 08 '17 at 14:47