如何使ng-transclude表现得像ng-include(在范围方面)?

时间:2022-04-02 22:51:08

I'd like to transclude content as such that it acts as if I copy-pasted the content into the file where I write my <div data-ng-transclude="">. How do I do this?

我希望将内容转换为内容,就像我将内容复制粘贴到我编写

的文件中一样。我该怎么做呢?

I know I can use ng-include to include a template, and I can use script tags to define a template. But this clutters the template cache and pollutes the template namespace.

我知道我可以使用ng-include来包含模板,我可以使用脚本标签来定义模板。但这会使模板缓存变得混乱并污染模板命名空间。

I want to do this so that I can have one (or more! That's the whole point) file in which I define the way I want to display my items,

我想这样做,这样我就可以有一个(或更多!这就是整点)文件,我在其中定义了我想要显示项目的方式,

<!-- list directive to show the items -->
<div data-item-list="" data-values="vm.items">

    <!-- content to include to display list items -->
    <div class="form-relation-picker-value" ng-bind="item.value.title"></div>
    <div class="form-relation-picker-subtitle" ng-bind="item.value.subTitle"></div>
</div>

and one file in which I define the way the list's structure works.

和一个文件,我在其中定义列表结构的工作方式。

<div class="list-container">
    <div class="list-item"
         data-ng-click="vm.select(item)"
         data-ng-repeat="item in vm.items | orderBy : vm.orderBy"
         data-selected="{{vm.isSelected(item)}}">

        <div class="flex">
            <div ng-transclude=""></div><!-- item display via transclude -->
            <div class="grid-col flex-icon form-relation-picker-chrome-height-fix">
                <div data-ng-show="vm.isSelected(item)" class="icon check"></div>
            </div>
        </div>
    </div>
</div>

This works if I do something like this:

如果我做这样的事情,这是有效的:

<div data-item-list="" data-values="vm.items" data-template-to-use="randomhash">
    <script type="text/ng-template" id="randomhash">
        <div class="form-relation-picker-value" ng-bind="item.value.title"></div>
        <div class="form-relation-picker-subtitle" ng-bind="item.value.subTitle"></div>
    </script>
</div>

with a list structure like so...

像这样的列表结构......

<div class="list-container">
    <div class="list-item"
         data-ng-click="vm.select(item)"
         data-ng-repeat="item in vm.items | orderBy : vm.orderBy"
         data-selected="{{vm.isSelected(item)}}">

        <div class="flex">
            <div data-ng-include="vm.templateToUse"></div>
            <div class="grid-col flex-icon form-relation-picker-chrome-height-fix">
                <div data-ng-show="vm.isSelected(item)" class="icon check"></div>
            </div>
        </div>
    </div>
</div>

But, like I said, it clutters the template cache.

但是,就像我说的那样,它会使模板缓存变得混乱。

If I transclude the content, then it stops working, as the transcluded content is evaluated with the scope of the directive that contains the <div data-item-list="". That is, "item" does not exist.

如果我转换内容,那么它将停止工作,因为使用包含

How can I make it so that the transcluded content is evaluated with the scope of the directive that is including the transcluded content?

如何使用包含被转换内容的指令范围来评估已转换的内容?

1 个解决方案

#1


2  

What you need, is a template function that will extract the content of your template element (the element as it appears in your HTML, before Angular compiles it) and embed it into the directive's template.

您需要的是一个模板函数,它将提取模板元素的内容(在Angular编译之前,HTML中出现的元素)并将其嵌入到指令的模板中。

As described in the docs, the template property of the DDO can be a function, in which case it receives the template element as an argument (among other things) and is expected to return the directive's template as a string.

如文档中所述,DDO的模板属性可以是一个函数,在这种情况下,它接收模板元素作为参数(以及其他内容),并期望将指令的模板作为字符串返回。

You can use something like this:

你可以使用这样的东西:

.directive('itemList', function itemListDirective() {
  // DDO
  return {
    ...
    template: function itemListTmplFn(tElem) {
      var customContent = tElem.html();

      return '...' + customContent + '...';
    }
  };
})

Here is a simple demo that uses the .component() API (introduced in v1.5). There are some minor differences if you want to use a plain old .directive(), but you should be able to adapt it easily.

这是一个使用.component()API(在v1.5中引入)的简单演示。如果你想使用一个普通的.directive(),你会有一些细微的差别,但你应该能够轻松地适应它。

#1


2  

What you need, is a template function that will extract the content of your template element (the element as it appears in your HTML, before Angular compiles it) and embed it into the directive's template.

您需要的是一个模板函数,它将提取模板元素的内容(在Angular编译之前,HTML中出现的元素)并将其嵌入到指令的模板中。

As described in the docs, the template property of the DDO can be a function, in which case it receives the template element as an argument (among other things) and is expected to return the directive's template as a string.

如文档中所述,DDO的模板属性可以是一个函数,在这种情况下,它接收模板元素作为参数(以及其他内容),并期望将指令的模板作为字符串返回。

You can use something like this:

你可以使用这样的东西:

.directive('itemList', function itemListDirective() {
  // DDO
  return {
    ...
    template: function itemListTmplFn(tElem) {
      var customContent = tElem.html();

      return '...' + customContent + '...';
    }
  };
})

Here is a simple demo that uses the .component() API (introduced in v1.5). There are some minor differences if you want to use a plain old .directive(), but you should be able to adapt it easily.

这是一个使用.component()API(在v1.5中引入)的简单演示。如果你想使用一个普通的.directive(),你会有一些细微的差别,但你应该能够轻松地适应它。