如何在指令模板

时间:2016-01-29 20:10:51

标签: javascript angularjs

我希望能够获得被抄送的内容。将其应用于指令中的ng-repeat。然后将每个ng-repeat的范围应用于已转换内容的克隆。

在另一个指令的部分内部我有这个:

...

<directive-b>
    // title is exposed here to directiveA but I want it to be changed to ng-repeat scope later
    <p>Hello {{title}}</p>
</directive-b>

...

inside directiveB指令

(function() {
    'use strict';
    angular.module('app')
        .directive('directiveB', DirectiveB);

    function DirectiveB() {
        return {
            restrict: 'E',
            transclude: true,
            scope: {},
            bindToController: {},
            compile: DirectiveBCompile,
            controller: DirectiveBController,
            controllerAs: 'vm',
            templateUrl: 'directive-b.partial.html'
        }
    }

    function DirectiveBCompile(cElem, cAttr, cTransclude) {
        // cTransclude is deprecated... so cant do this here
        return InfiniteScrollLink;
    }

    function DirectiveBController() {
        var vm = this;
    }

    function DirectiveBLink(scope, element, attrs, controller, transclude) {
        // ideally would be great to somehow apply ng-repeat scope to each transcluded element here, but I couldn't

        scope.data = [{
            title: 12345
        }, {
            title: 345245
        }, {
            title: 32452345
        }];
        // this scope doesn't get picked up either
        scope.title = "12345";
    }
})();

inside directiveB指令部分

<ul>
    <li data-ng-repeat="data in vm.data" data-ng-transclude>
    </li>
</ul>

有没有办法将ng-repeat中的“数据”作为转换范围传递?

我想看到的是:

<ul>
    <li>
        <p>Hello 12345</p>
    </li>
    <li>
        <p>Hello 345245</p>
    </li>
    <li>
        <p>Hello 32452345</p>
    </li>
</ul>

2 个答案:

答案 0 :(得分:1)

我能够以非常肮脏的方式做到这一点。

<directive-b>
    // just want to point out that this is **probably** the only way to pass
    // data-bind inside this element as otherwise scope would be overwritten
    <div ng-controller="DirectiveBTemplate as template">
        <p>Hello {{template.data.title}}</p>
    </div>
</directive-b>

然后,

<ul>
    // data="data" is crucial here, basically sets data to ng-repeat scope
    <li data-ng-repeat="data in vm.data" data="data" data-ng-transclude>
    </li>
</ul>

然后,

(function() {
    'use strict';
    angular.module('app.widgets')
        .controller('DirectiveBTemplate', DirectiveBTemplate)
        .directive('directiveB', DirectiveB);
    DirectiveBTemplate.$inject = ["$scope"];

    function DirectiveBTemplate($scope) {
        // I'm basically assigning ng-repeat scope and setting it to DirectiveBTemplate scope, them im retrieving data from ng-repeat.
        $scope = $scope.$parent.$parent;
        this.data = $scope.data;
    }

答案 1 :(得分:0)

呃,很遗憾没人接过这个问题。对于那些可能正在寻找答案的人来说:

实际上,您可以为指令中包含的元素提供所需的任何范围 - 您只需要使用transclude函数,如下例所示:

angular.module('MyApp', [])
  .directive('myDirective', myDirective);

function myDirective() {
  return {
    scope: {},
    restrict: 'E',
    transclude: true,
    link: MyDirectiveLinker,
    template: 'Yes, he is' // see? No ng-transclude attribute in directive's template. Why? Look inside of the link function
  };

  /////

  function MyDirectiveLinker ($scope, $element, $attrs, $ctrl, $transclude) {
    $scope.arrow = ' <- '; // our 'inner' variable

    $transclude(
      $scope, // and here, you attach directive's scope to the transcluded element
      function(_transcludedElement, _scope) {
        $element.prepend(_transcludedElement);
      }
    );
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>

<main ng-app="MyApp">
  <my-directive>
    I use data of directive's scope{{arrow}}
  </my-directive>
</main>