javascripthtmlangularjsangularjs-templates

AngularJS create partial template with parameter


I have gone through below SO questions to get what I want.

create a single html view for multiple partial views in angularjs

Partial views in AngularJS

AngularJs Include Partial Template

angularjs partial template with specific scope - looks close to what I want.

But I believe my case is different from all of them. Hence, the question.

I have got this HTML structure which needs to be repeated numerous times.

<tr>
    <td>
        Enitity1
    </td>
    <td>
        <input type="radio" name="entity1" value="option1" />
    </td>
    <td>
        <input type="radio" name="entity1" value="option2" />
    </td>
    <td>
        <input type="radio" name="entity1" value="option3" />
    </td>
    <td>
        <input type="radio" name="entity1" value="option4" />
    </td>
    <td>
        <input type="radio" name="entity1" value="option5" />
    </td>
</tr>

I want to pass the name of the Entity as a parameter and render this HTML template based on the parameter.

I have created a template like below.

<tr>
    <td>
        {{entity}}
    </td>
    <td>
        <input type="radio" name="{{entity}}" value="option1" />
    </td>
    <td>
        <input type="radio" name="{{entity}}" value="option2" />
    </td>
    <td>
        <input type="radio" name="{{entity}}" value="option3" />
    </td>
    <td>
        <input type="radio" name="{{entity}}" value="option4" />
    </td>
    <td>
        <input type="radio" name="{{entity}}" value="option5" />
    </td>
</tr>

My controller

app.controller("entitiesController", ["$scope",
    function entitiesController($scope) {
        $scope.init = function init(entity) {
            $scope.entity= entity;
        };
    }
]); 

And I am trying to render the same for multiple entities as below inside a <tbody> element.

<ng-include src="Common/entities.html" ng-controller="entitiesController" ng-init="init('Entity1')"></ng-include>
<ng-include src="Common/entities.html" ng-controller="entitiesController" ng-init="init('Entity2')"></ng-include>
<!-- Some more entities here...-->

But it does not work. It does not throw any error as well in the console.

How do I go about this? What is the proper way of handling this? Is it possible to handle it with a template or should I just put HTML for all the entities manually?


Solution

  • You can have a directive to do this for you. Something like,

    myApp.directive("myEntity", function() {
      return {
        restrict: "E",
        scope: {
          entity: "="
        },
        templateUrl: "Common/entities.html"
      }
    })
    

    Now, you can use the template you already created in Common/entities.html which is,

    <tr>
        <td>
            {{entity}}
        </td>
        <td>
            <input type="radio" name="{{entity}}" value="option1" />
        </td>
        <td>
            <input type="radio" name="{{entity}}" value="option2" />
        </td>
        <td>
            <input type="radio" name="{{entity}}" value="option3" />
        </td>
        <td>
            <input type="radio" name="{{entity}}" value="option4" />
        </td>
        <td>
            <input type="radio" name="{{entity}}" value="option5" />
        </td>
    </tr>
    

    Finally, use it like <my-entity entity="entityObj"></my-entity> where entityObj is a variable in your $scope (or accordingly if you use controllerAs syntax)

    EDIT: Other way is to have the directive as attribute and not element.

    myApp.directive("myEntity", function() {
      return {
        restrict: "A",
        ...
      }
    })
    

    And, remove the <tr> from the template. Now, we can use it like,

    <tbody>
      <tr my-entity entity="entityObj">
      </tr>
    </tbody>