web-dev-qa-db-ja.com

AngularJSディレクティブで定義されたtext / ng-templateを使用する方法

私は非常に柔軟なディレクティブを作成しようとします。そうするために、私はユーザーに私のリターンの一部で使用されるテンプレートを定義してほしいです( i-bootstrap typeahead directive で見られるように)。

だから私はこのようにテンプレートを定義します:

<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>

このテンプレートをディレクティブに設定します

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

今私のディレクティブでは、どのようにカスタムテンプレートをレンダリングし、渡されたデータで使用できますか?テンプレートを直接返すために使用しようとすると、ReferenceError: $scope is not definedエラー。スコープなしで呼び出すと、ReferenceError: myDirectiveCustomTemplate is not definedエラー。

リターンとして直接使用したくない場合、どこでどのようにテンプレートを使用できますか?

編集:たとえば、これは私の指示です:

(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

ディレクティブを見て、ng-includeを試すことをお勧めします。あなたがしたい場所

//$compile(ComboboxDropdownTemplate) +

    '</div>'

に変更する

<span ng-include='templateUrlPropertyOnScope'>

'</div>'

templateUrlPropertyOnScopeプロパティは、サーバー側または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

$httpおよび$compileを使用して、このようなタスクを達成できます。

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);
      });
    }
  };
});

良いスタートになることを願っています

3
Utopik

私はこれが4年後であることを知っていますが、誰かがまだこの質問を持っているなら、おそらくこの答えも役に立つかもしれません。

このような単純なディレクティブを使用すると:

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

次のように、ディレクティブのテンプレート属性を参照できます。

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

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