使用ng-transclude强制范围到命名槽 [英] Force scope to named slot with ng-transclude

查看:137
本文介绍了使用ng-transclude强制范围到命名槽的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的指令如下:

<selectable-item-list items="model.items">
    <item-template>
          <span ng-bind="item.text"></span>
    </item-template>
</selectable-item-list>

问题出在< item-template> ng-repeat ,其中 item 将是当前迭代项的引用$ c>绑定在< selectable-item-list> 中。

The issue is in the <item-template>, where item would be a reference of currently iterated item when an internal ng-repeat is bound inside <selectable-item-list>.

AFAIK,似乎transclusion无法看到指令的范围,因此, item.text 不能因为根本没有项目而受到约束。

AFAIK, it seems like transclusions can't see directive's scope, thus, that item.text can't be bound because there's no item at all.

您将如何解决这种情况?之前我手动转换< item-template> 但其他方法还有其他缺点/问题。

How would you solve this scenario? Previously I was manually-transcluding <item-template> but that other approach had other downsides/issues.

这是一个可运行的代码片段,作为我的真实案例的样本:

Here's a runnable code snippet that works as sample of my real-world case:

var app = angular.module("app", []);

app.controller("some", function() {
  this.items = [{
    text: "hello"
  }, {
    text: "bye"
  }];
});

app.directive("test", function() {
  return {
    template: `<ol>
                  <li ng-repeat="item in items">
                      <div ng-transclude="itemTemplate"></div>
                  </li>
                </ol>`,
    transclude: {
      "itemTemplate": "itemTemplate"
    },
    scope: {
      "items": "="
    }
  }
});

<script src="https://code.angularjs.org/1.5.7/angular.js"></script>

<div ng-app="app" ng-controller="some as some">
  <test items="some.items">
    <item-template>
      <span ng-bind="item.text"></span>
    </item-template>
  </test>
</div>

推荐答案

我的假设错了!当我说被翻译的内容无法访问包含指令范围时,我错了,因为这个其他问答A:为什么ng-transclude的范围不是其指令范围的子代 - 如果指令具有隔离范围?这绝对是过时的。

I had a wrong assumption! When I said that a transcluded content couldn't access the containing directive scope I was wrong because of this other Q&A: Why ng-transclude's scope is not a child of its directive's scope - if the directive has an isolated scope? which is absolutely outdated.

事实上,作为同一个Q& A的一部分还有另一个答案,有人描述现在已经修复了这个问题并且包含内容的内容可以使用 $ parent 访问其直接指令范围。

In fact, there's another answer as part of the same Q&A where someone has described that now this has been fixed and a transcluded content can access its direct directive scope using $parent.

所以我修复了我的问题,只需用 $ parent.item 替换属性访问权限!

So I fixed my issue just replacing the item property access with $parent.item and it worked!

我添加了一个包含此修复程序的工作代码段:

I've added a working code snippet which has this fix:

var app = angular.module("app", []);

app.controller("some", function() {
  this.items = [{
    text: "hello"
  }, {
    text: "bye"
  }];
});

app.directive("test", function() {
  return {
    template: `<ol>
                  <li ng-repeat="item in items">
                      <div ng-transclude="itemTemplate"></div>
                  </li>
                </ol>`,
    transclude: {
      "itemTemplate": "itemTemplate"
    },
    scope: {
      "items": "="
    }
  }
});

<script src="https://code.angularjs.org/1.5.7/angular.js"></script>

<div ng-app="app" ng-controller="some as some">
  <test items="some.items">
    <item-template>
      <span ng-bind="$parent.item.text"></span>
    </item-template>
  </test>
</div>

这篇关于使用ng-transclude强制范围到命名槽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆