Lusk116
Lusk116

Reputation: 1050

AngularJs Directive - <script> inside template

I have a directive with a template and inside this template I have a <script> tag using variables of the directive.

Directive:

    (function () {
      'use strict';

      angular
        .module('app.components')
        .directive('picker', Picker);

      /*@ngInject*/
      function Picker() {

        return {
          restrict: 'E',
          controller: PickerController,
          controllerAs: 'vm',
          bindToController: true,
          templateUrl: 'picker.html',
          transclude: true,
          scope:{
            inputId: '@'
          }
        };

        /*@ngInject*/
        function PickerController() {
          /*jshint validthis: true */
          var vm = this;
        }

      }
    })();

Template:

    <div>
      <div>
        id: {{vm.inputId}}
        <ng-transclude></ng-transclude>
      </div>
      <script>
        console.log({{vm.inputId}});
      </script>
    </div>

Usage:

    <picker input-id="myInput"> <!-- something... --> </picker>

The problem is that the {{vm.inputId}} inside the <script> tag isn't filtered so {{vm.inputId}} doesnt become "myInput". Everything works outside the <script> tag, id: {{vm.inputId}} becomes id: myInput

Is it just not possible to put "variables" inside a script tag?

Upvotes: 4

Views: 10490

Answers (4)

Patrick
Patrick

Reputation: 1121

The piece of code that is implemented in

<script>
      console.log({{vm.inputId}});
</script>

can be well implemented inside your directive's controller. That will allow you to run the javascript code with the luxury of having access to your variables.

For example you can have this:

var app =  angular.module('myApp', [])

app.directive('testDirective', function(){
  return {
    restrict: 'E',
    template: '<p>Click in the text box</p>'+
              '<textarea id="my-area"></textarea>'+
              '<p>Click {{num_clicks}}</p>',
    controller: function($scope, $log){
      $scope.num_clicks = 0;
      $("#my-area").click(function(){
        incr();
      });
      function incr(){
        $scope.num_clicks = $scope.num_clicks + 1;
        $scope.$digest();
        $log.log("A click",   $scope.num_clicks);
      }

    }
  };
});

I hope this helps

Upvotes: 2

William B
William B

Reputation: 1419

just include the library script with the rest of your scripts (angular etc) on your index.

You can still wrap the datepicker in a directive -- use the link function of the directive. if jQuery is in your project you will have access to all jquery functions on the "element" parameter of your link function.

angular.module('myModule').directive('datepicker', function () {
  return {
    link: function (scope, elem, attrs) {
      elem.jqdatepicker({ /* options */ });
    }
  };
});

Upvotes: 0

Buh Buh
Buh Buh

Reputation: 7546

I would not recommend using a <script> tag inside your template at all.

If you want to log the value of inputId at the moment the view is loaded then you could use the ngInit directive instead.

<div ng-init="log(vm.inputId)">
    id: {{vm.inputId}}
    <ng-transclude></ng-transclude>
</div>

and add the log function to your scope in the controller:

app.controller('myController', function($scope, $log) {
    $scope.log = function (message) {
        $log.log(message)
    };
});

Upvotes: 1

nalinc
nalinc

Reputation: 7425

Well, jQlite does not support script tags in templates. jQuery does, so the recommendation is to include jQuery if you need this functionality.

Further,

Even if you use the <script> tag in your template, the code within would be executed outside angular's context. So you would not be able to access any variable inside controller's scope in your <script> tag within the template file. This essentially means, doing something like

  <script>
    console.log({{vm.inputId}});
  </script>

is not possible, because neighter vm, nor inputId would be available and you would infact get an error claiming Unexpected token {{

Again, you could have written the same code in controller anyways. So why complicate things

If you still intend to use the <script> within your template, here's a plunkr

Upvotes: 0

Related Questions