0

I have an AngularJS app that displays several plots. Each plot has a set of date controls to allow the user to change the start and end dates of the plotted data range. The date controls are loaded as a partial template in a uib-popover.

I've been using separate partial templates for each plot. I include the template in the page between <script type="text/ng-template"></script> tags, and load it using <button uib-popover-template="foo">Controls</button>.

This works fine, but having separate templates for each plot seems very repetitive, especially since I have several plots on the page. I tried creating a single template, setting the name of the plot for that "instance" of the template using ng-init, and hoping that would allow me to dynamically load the plot values into the template for that particular plot. Something along the lines of this:

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
  $scope.plots = {
    "goodPlot": {
      "start": "1/1/2018",
      "end": "1/1/2019"
    },
    "betterPlot": {
      "start": "5/5/2018",
      "end": "3/10/2019"
    }
  };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<div ng-app="myApp" ng-controller="myCtrl">
  <h4>First Plot</h4>
  <div ng-init="thisPlot = plots.goodPlot" ng-include="'plotControls.tmpl'"></div>
  <hr/>
  <h4>Second Plot</h4>
  <div ng-init="thisPlot = plots.betterPlot" ng-include="'plotControls.tmpl'"></div>

  <script type="text/ng-template" id="plotControls.tmpl">
    <div class="form-group">
      <label class="control-label">Start Date</label>
      <input type="text" class="form-control" ng-model="thisPlot['start']">
    </div>
    <div class="form-group">
      <label class="control-label">End Date</label>
      <input type="text" class="form-control" ng-model="thisPlot['end']">
    </div>
  </script>
</div>

But as you can see, the start/end dates for both plots are the same. I understand why this is -- they're both binding to the same variables. But I can't figure out a solution to achieve the desired result.

Basically, I'm looking to create multiple "instances" of the same template, but with different variable values to be set before the ng-include.

Can anyone offer any suggestions?

1 Answer 1

1

Use a component to instantiate the template:

app.component("myPlotControls", {
    bindings: { "plot", "<" },
    templateUrl: "plotControls.tmpl",
})

Usage:

<my-plot-controls plot="plots.goodPlot"></my-plot-controls>

<my-plot-controls plot="plots.betterPlot"></my-plot-controls>

  <script type="text/ng-template" id="plotControls.tmpl">
    <div class="form-group">
      <label class="control-label">Start Date</label>
      <input type="text" class="form-control" ng-model="$ctrl.plot['start']">
    </div>
    <div class="form-group">
      <label class="control-label">End Date</label>
      <input type="text" class="form-control" ng-model="$ctrl.plot['end']">
    </div>
  </script>

Components create an isolate scope so that multiple instantiations of the same template will not conflict in the parent scope.

For more information, see

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

Comments

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.