角度`@Host`装饰器没有到达顶部?

2024-05-01

在我的主要app.ts我已宣布成为全球提供商:

providers: [{provide: Dependency, useValue: createDependency('AppModule provider')}]

(Where createDependency只是一个返回一个类的函数,该类具有getName() method.)

我还有一个组件:

    <my-app-component-3>Hello from 3</my-app-component-3>

Code :

@Component({
    selector: 'my-app-component-3',
    template: `
        <div>Component3:
            <ng-content></ng-content>
            : <span [innerHTML]="dependency?.getName()"></span>
        </div>
    `,

})
export class Component3 {
    constructor(@Host() @Optional() public dependency: Dependency) {}
}

结果是:

组件 3:来自 3 的问候:

但我期望结果是:

组件 3:来自 3 的问候:应用程序模块提供商

因为基本上应用程序结构是:

<my-app>
  <my-app-component-3>
  </my-app-component-3>
</my-app> 

问题:
为什么不@Host()与父提供者匹配 ?

(即:providers: [{provide: Dependency, useValue: createDependency('AppModule provider')}])

据我所知 - 注射器应该寻求Dependency以这种方式 :

那么为什么它找不到呢?

PLUNKER https://plnkr.co/edit/qpsUzaAywtkN6JfbFXMb?p=preview

Notice

我已经知道如果我删除@host- 它确实达到了顶峰。我的问题是为什么添加 @host - 没有到达顶部 - 尽管事实上my-component3在下面my-app !!


查看Angular 中 @Host 装饰器和元素注入器的一个奇怪案例 https://blog.angularindepth.com/a-curios-case-of-the-host-decorator-and-element-injectors-in-angular-582562abcf0a深入解释 @Host 装饰器如何工作以及元素注入器在这张图中的作用。

为了让它工作,你应该在在父组件中并使用视图提供者:

@Component({
  selector: 'my-app',
  viewProviders: [{provide: Dependency, useValue: createDependency('AppModule provider')}],
    ...
export class MyApp {}

这是里面的评论元数据.ts https://github.com/angular/angular/blob/cbd93fe0d0624ce5920f966027df534fd9b50b85/packages/core/src/di/metadata.ts#L252 say:

指定注入器应该从任何 注射器until到达当前组件的宿主元素。

所以基本上它说的是一个主机元件注入器和上面的所有注入器are not解决依赖关系时使用。所以如果你的MyApp组件具有以下模板:

<my-app-component-3></my-app-component-3>

生成的组件树如下所示:

<my-app>
    <my-app-component-3></my-app-component-3>
</my-app>

neither MyApp组件的注入器或应用程序模块注入器are用于解决依赖关系my-app-component-3.

然而,有以下有趣的代码ProviderElementContext._getDependency https://github.com/angular/angular/blob/9dc310eb50f022b25184e84a3a9abc016e4a2451/packages/compiler/src/provider_analyzer.ts#L290执行一项附加检查:

// check @Host restriction
if (!result) {
    if (!dep.isHost || this.viewContext.component.isHost ||
       this.viewContext.component.type.reference === tokenReference(dep.token !) ||
       // this line
       this.viewContext.viewProviders.get(tokenReference(dep.token !)) != null) { <------
       result = dep;
    } else {
       result = dep.isOptional ? result = {isValue: true, value: null} : null;
    }
}

它基本上检查提供者是否在中定义viewProviders并解决(如果找到)。这就是为什么viewProviders work.

所以,这是查找树:

Usage

该装饰器主要用于从当前组件视图中的父注入器解析提供程序的指令。即便是单元测试已编写 https://github.com/angular/angular/blob/master/packages/examples/core/di/ts/metadata_spec.ts#L135仅用于测试指令。这是一个真实的例子forms模块如何使用它的装饰器。

考虑此模板A成分:

<form name="b">
    <input NgModel>
</form>

NgModel指令想要解析由form指示。但如果提供者不可用,则无需超出当前组件的范围A.

So NgModel定义如下:

export class NgModel {
    constructor(@Optional() @Host() parent: ControlContainer...)

While form指令定义如下:

@Directive({
  selector: '[formGroup]',
  providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }],
  ...
})
export class NgForm

此外,指令可以注入由其托管组件定义的依赖项(如果它们是用以下命令定义的)viewProviders。例如,如果MyApp组件定义如下:

@Component({
    selector: 'my-app',
    viewProviders: [Dependency],
    template: `<div provider-dir></div>`
})
export class AppComponent {}

the Dependency将会得到解决。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

角度`@Host`装饰器没有到达顶部? 的相关文章

  • 如何使用键盘和鼠标控制相机 - Three.js

    我在 WEB GL 中有一个带有 Three js 的 3D 环境 并且我曾经使用 Orbitcontrols js http codepen io nireno pen cAoGI http codepen io nireno pen c
  • 从 x,y 屏幕空间坐标查找 2D 等距网格上的列、行(将方程转换为函数)

    我试图在屏幕空间点 x y 的二维等距网格中找到行 列 现在我几乎知道我需要做什么 即找到上图中红色向量的长度 然后将其与表示网格边界的向量的长度 由黑色向量表示 进行比较 现在我在数学堆栈交换中寻求帮助 以获得用于计算点 x y 与黑色边
  • 限制文本区域中每行的字符数

    我整个周末都在寻找解决这个难题的方法 但尚未找到一个可以正常工作的解决方案 我想要实现的是限制文本区域中每行的字符数 不是相同地限制它们 而是我选择的每行不同的字符数 例如 我只想在我的文本区域中包含 4 行 第 1 2 和 3 行将限制为
  • 使用 Javascript 在 Imacros 中循环

    我如何使用 javascript 循环 imm imacros 脚本 我搜索了一下 发现了这个 for i 0 i lt n i iimPlay marconame iim 但当我使用它时 我的浏览器 Firefox 18 挂起 for i
  • ant-d upload中如何为removeFile添加PopConfirm一个图片文件

    我正在使用 Ant d Upload 通过本地系统上传文件 然后单击文件预览图像上的删除图标 图像文件将被删除 我想添加一个弹出确认 所以我尝试在 onRemovefunction 中添加确认作为承诺但它不起作用 它在浏览器中显示警报 on
  • 如何在 Angular 中实现使用 google 登录

    我正在尝试在我的角度应用程序中实现谷歌登录功能 我这里用了两个包 abacritt angularx social login and angular oauth2 oidc 我创建了一个名为的自定义提供程序google authentic
  • 在 BIRT 中输入参数后更新数据集查询

    在 BIRT 报告设计中传递参数后 如何更改或更新数据集的查询 详细说明 我有一个如下所示的查询 WHERE 该参数标记可以保存不同的值 在用户输入参数后 它看起来像这样 例如 WHERE column name 1 or WHERE co
  • 未捕获的引用错误:myFunction 未定义[重复]

    这个问题在这里已经有答案了 这到底是怎么回事 http jsfiddle net sVT54 http jsfiddle net sVT54
  • 在 MVC Razor 中的 C# 和 Javascript 之间共享常量

    我想在服务器上的 C 和客户端上的 Javascript 中都使用字符串常量 我将常量封装在 C 类中 namespace MyModel public static class Constants public const string
  • 保存/导出Chrome的JavaScript控制台输入历史记录

    无论如何 我可以保存或导出 JavaScript 控制台的历史记录吗 input 控制台历史记录 在 Google Chrome 中 我不想保存输出或错误 因此将鼠标悬停在控制台框上 右键单击并选择Save as 不是解决方案 我不想每次都
  • 如何记录返回的事件发射器

    如何记录所发出的事件stream返回于MyFunc 与 JSDoc MyFunc description param Object opts description return Stream description function My
  • 在 Angular 材质表上调用 renderRows()

    我试图在更新表中使用的数据后刷新我的 Angular 表 文档说 您可以通过调用其 renderRows 方法来触发对表的渲染行的更新 但它不像普通的子组件 我可以使用 ViewChild MatSort sort MatSort 因为我不
  • 用数组反向查找对象

    假设我有一个这样的对象 resourceMap a 0 1 2 3 4 5 6 7 8 9 10 b 11 12 c 21 23 d 54 55 56 57 510 确定是否的最佳方法是什么resourceId 21将会 c 我们不知道钥匙
  • 角度 2 中的动态 styleUrls?

    是否可以将样式表的 url 动态注入到组件中 就像是 styleUrls stylesheet1 css this additionalUrls 或者 一厢情愿并注意这只是假代码 export class MyComponent imple
  • 如何清除WebGL中的矩形区域?

    WebGL 有一个clear清除整个表面的方法 清除表面的特定矩形的最佳方法是什么 例如 我想将一个从 50 50 开始的 100x100 像素框设置为全零 ARGB 0 0 0 0 我现在能想到的就是用一个写入零的片段着色器绘制一个四边形
  • Flux + React.js - 操作中的回调是好还是坏?

    让我解释一下我最近遇到的问题 我有 React js Flux 驱动的应用程序 有一个列表显示文章数量 注意 应用程序中有多个不同的列表 和文章详情查看在里面 但每个列表只有一个 API 端点 它返回文章数组 为了显示我需要的详细信息fin
  • Jquery:选择菜单以显示和隐藏某些div元素

    我正在创建一个选择菜单 根据所选选项显示和隐藏某些 div 像这样的东西
  • 如何获取使用 .map 渲染的第一个元素的 ref?

    我需要在几行中显示视频 卡片 的缩略图 并重点关注第一个缩略图 我使用嵌套地图进行了显示 该代码基本上迭代视频数组并返回多行视频 我们如何关注第一个渲染的元素 我认为我们需要获得第一个要聚焦的元素的引用 但是我们如何在这里设置 ref 并在
  • 您如何看待引导模式触发器的相应回调?

    On 引导模态 http getbootstrap com javascript modals 我们知道我们可以为触发器绑定事件 例如show or hide using show shown hide hidden 但此事件绑定仅适用于一
  • 在 javascript 中使用 xPath 解析具有默认命名空间的 XML

    我需要创建一个 XML xPath 解析器 所有解析都必须在客户端进行 使用 JavaScript 我创建了一个 javascript 来执行此操作 在默认名称空间发挥作用之前 一切看起来都正常 我根本无法查询具有默认命名空间的 XML 我

随机推荐