【问题标题】:How to change a scope of transcluded elements to a ng-repeat item scope within directive template如何在指令模板中将嵌入元素的范围更改为 ng-repeat 项目范围
【发布时间】:2016-05-07 16:48:22
【问题描述】:

我希望能够获得嵌入的内容。将其应用于指令中的 ng-repeat。然后将每个 ng-repeat 的作用域应用到转入内容的克隆。

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

...

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

...

在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";
    }
})();

内部指令B指令部分

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

有什么方法可以将 ng-repeat 中的“数据”作为 transclude 的范围传递?

我想看到的是:

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

【问题讨论】:

  • 也许可以创建一个子 div,或者找出 $scope.data 的列出位置
  • 可能是 data-ng-transclude="data"?我已经有一段时间没有使用 angular
  • data-ng-transclude="data" 用于多槽嵌入,例如 transclude: { * 'data': '?data', 将指向包含在 transclude 中的数据元素
  • 我也在使用 angular 1.4.7,在 1.5 中引入了多槽嵌入 :(

标签: javascript angularjs


【解决方案1】:

呃,很遗憾没有人回答这个问题。对于可能正在寻找答案的人:

实际上,您可以为指令中嵌入的元素提供任何您想要的范围 - 您只需要为此使用 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>

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-07-01
      • 2013-03-15
      • 1970-01-01
      • 2013-01-17
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 2015-11-06
      • 1970-01-01
      相关资源
      最近更新 更多