web-dev-qa-db-fra.com

Comment utiliser le modèle text / ng défini dans la directive AngularJS

J'essaie d'écrire une directive très flexible. Pour ce faire, je veux que l'utilisateur définisse un modèle utilisé dans une partie de mon retour (comme vu dans la directive ui-bootstrap typeahead ).

Je définis donc mon modèle comme ceci:

<script type="text/ng-template" id="myDirectivesCustomTemplate.html">
  <ul>
    <li ng-repeat="value in values">
      <a ng-click="doSomething(value.id)">
        {{value.name}}
      </a>
    </li>
  </ul>
</script>

J'ai défini ce modèle dans ma directive

<div 
  my-directive 
  my-directive-custom-template="myDirectivesCustomTemplate.html" 
  my-directive-data="someScopeData">

Maintenant dans ma directive, comment puis-je rendre le modèle personnalisé et l'utiliser avec les données transmises? Lorsque j'essaie de l'utiliser pour retourner directement dans le modèle, il jette un ReferenceError: $scope is not defined Erreur. Si je l'appelle sans portée, il dit ReferenceError: myDirectiveCustomTemplate is not defined Erreur.

Où et comment puis-je utiliser mon modèle si je ne veux pas simplement l'utiliser comme retour directement?

EDIT: disons, voici ma directive:

(function() {
 'use strict';
 var Combobox = function() {

  var displayInputField     = elem.find('input.dropdown');

  scope.$watch(scope.nsdComboboxModel,function(newVal){
    /* search for newVal in given data object */
    scope.setDisplayInputValue(newVal);
  });

  scope.setDisplayInputValue = function(value)
  {
    displayInputField.val(value);
  };

  scope.elementSelected = function (item, model, label) {
    scope.ComboboxCallback(item);
    scope.setDisplayInputValue(label);
  };
 }


 return {
   restrict: 'A',
   transclude: true,
   scope: {
     Combobox:                  '@', /* used as HTML/CSS-id/name/path */
     ComboboxModel:             '=', /* the actual AngularJS model (ng-model) */
     ComboboxAutocompleteData:  '=', /* the data used for autoComplete (must be array of objects having id and value) */
     ComboboxDropdownData:      '=', /* data used by the dropdown template */
     ComboboxCallback:          '=', /* a callback function called with selected autocomplete data item on select */
     ComboboxLabel:             '@', /* label for the input field */
     ComboboxDropdownTemplate:  '@'  /* label for the input field */
 },

 template:

  '<section class="-combobox-directive container-fluid">' +
    '<label for="{{Combobox}}" ng-if="ComboboxTranslation" translate="{{ComboboxLabel}}"></label>' +
    '<div class="combobox input-group">' +
      '<input type="text" ' +
        'id="{{Combobox}}" ' +
        'autocomplete="off" ' +
        'ng-model="ComboboxDestinationDisplay" ' +
        'data-toggle="dropdown" ' +
        'typeahead="value as location.value for location in ComboboxAutocompleteData | filter:$viewValue" ' +
        'typeahead-editable="false" ' +
        'typeahead-on-select="elementSelected($item, $model, $label)" ' +
        'class="form-control dropdown">' + // dropdown-toggle

        '<span data-toggle="dropdown" class="input-group-addon dropdown-toggle">' +
          '<span class="glyphicon glyphicon-globe"></span>' +
        '</span>' +

        //$compile(ComboboxDropdownTemplate) +

    '</div>' +
  '</section>',

  link: link
 };
};

angular.module('vibe.directives').directive('nsdCombobox', [NsdCombobox]);
})();
24
Andresch Serj

En regardant votre directive, je peux suggérer d'essayer ng-include. Où voulez-vous faire

//$compile(ComboboxDropdownTemplate) +

    '</div>'

le changer en

<span ng-include='templateUrlPropertyOnScope'>

'</div>'

La propriété templateUrlPropertyOnScope doit pointer vers un modèle côté serveur ou dans la section de script créée avec type=text/ng-template.

13
Chandermani

HTML

<script type="text/ng-template" id="myDirectivesCustomTemplate.html">
    <ul>
        <li ng-repeat="value in values">
        <a ng-click="doSomething({id:value.id})">
                            {{value.name}}
        </a>
        </li>
    </ul>
</script>
<div ng-controller="MainCtrl">
     <div my-directive template="myDirectivesCustomTemplate.html" mydata="mydata" mycallback="doSomething(id)"></div>
</div>

JS

app.controller('MainCtrl',function($scope){
    $scope.mydata = [{id:1,name:'One'},{id:2,name:'Two'},{id:3,name:'Three'}];
    $scope.doSomething = function(id){
        alert(id); 
    }
});
app.directive('myDirective', function($templateCache,$compile) {
    return {
        restrict: 'A',
        scope:{
            template : "@",
            mydata : "=",
            mycallback:"&"
        },
        link: function(scope,element) {
            var template = $templateCache.get(scope.template);
            scope.values = scope.mydata;
            scope.doSomething = scope.mycallback;
            element.append($compile(template)(scope));
        }
    }
});
15
Whisher

vous pouvez utiliser $http et $compile pour réaliser une telle tâche.

app.directive('myDirective', function($http, $templateCache, $compile) {
  return {
    scope: {
      // reference to your data. 
      // Just use `data.values` or `data.whatever` in your template
      data: '=myDirectiveData'
    },
    link: function(scope, Elm, attrs) {
      // Load the template via my-directive-custom-template attribute
      $http.get(attrs.myDirectiveCustomTemplate, {cache: $templateCache}).success(function(html) {
        // update the HTML
        Elm.html(html);
        // compile the html against the scope
        return $compile(Elm.contents())(scope);
      });
    }
  };
});

J'espère que ça vous donne un bon départ

3
Utopik

Je sais que c'est 4 ans plus tard, mais si quelqu'un a encore cette question, peut-être que cette réponse peut également être utile.

Avec une simple directive comme celle-ci:

<my-directive template="custom-template.html"></my-directive>

Vous pouvez ensuite vous référer à l'attribut template dans votre directive, comme ceci:

(function() {
  angular
    .module('app')
    .directive('myDirective', myDirective);

  function myDirective() {
    return {
      restrict: 'E',
      templateUrl: function(elem, attrs) {
        return attrs.template;
      }
    }
  }
}
3
Jordan Stubblefield