Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Including components procedurally in AngularJS

I have an array of objects. Each of these objects has a "component" property with a string value. Now I would like to loop through the list and render each of the referenced components. Other properties of the looped objects are supposed to provide parameters for the components (not included in example below).

My solution so far works, but requires stating the allowed elements in a switch-case and creates unwanted wrapper elements:

angular.module('switchExample', [])
      .controller('ExampleController', ['$scope',
        function($scope) {
          $scope.items = [{
            component: "alpha"
          }, {
            component: "beta"
          }, {
            component: "alpha"
          }];
        }
      ])
      .component('alpha', {
        template: "this is component alpha",
      })
      .component('beta', {
        template: "this is component beta"
      })
<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Example</title>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
</head>

<body ng-app="switchExample">
  <div ng-controller="ExampleController">
    <div ng-repeat="s in items" ng-switch="s.component">
        <alpha ng-switch-when="alpha"></alpha>
        <beta ng-switch-when="beta"></beta>
    </div>
  </div>
</body>

</html>

Is there a way to include the components procedurally without the round-trip of string comparison and explicit invocation?

Something like this, maybe?:

<div ng-repeat="s in items">
    <component ng-component="s.component"></component>
</div>

or even better:

<div ng-repeat="s in items" ng-component="s.component"></div>

or alternatively:

<div ng-component="s.component for s in items"></div>
like image 329
Hubert Grzeskowiak Avatar asked Jul 26 '16 20:07

Hubert Grzeskowiak


1 Answers

Full documentation and download at GitHub: https://github.com/hubertgrzeskowiak/angular-component-directive.

Based on my answer below, I have re-implemented this in a rather clean and more versatile fashion. Demo: http://plnkr.co/edit/uDxIUulQPx4C3s11b5cG?p=preview

Usage (see GitHub fore full docs):

<component name="expr" args="expr" replace="expt"></component>

...where "name" expression must evaluate to a component name (string), "args" (optional) must evaluate to an object and "replace" (optional) must evaluate to a boolean. args are unpacked to attributes for the new component, so every value in that object is an expression. If "replace" is true, the component replaces itself.

like image 60
Hubert Grzeskowiak Avatar answered Oct 17 '22 00:10

Hubert Grzeskowiak