什么是RendererAdapter? [英] What is the RendererAdapter?

查看:70
本文介绍了什么是RendererAdapter?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然我无法重现该问题,但请查看我的朋克车

While I couldn't reproduce the issue, please take a look my plunker.

当我尝试在本地工作区中打开对话框时收到以下错误:

I received following error when I try to open the dialog in my local workspace:

ERROR TypeError: this._renderer.setProperty is not a function
at NgbRadio.set [as value] (radio.js:133)
at updateProp (core.es5.js:11160)
at checkAndUpdateDirectiveInline (core.es5.js:10852)
at checkAndUpdateNodeInline (core.es5.js:12382)
at checkAndUpdateNode (core.es5.js:12321)
at debugCheckAndUpdateNode (core.es5.js:13180)
at debugCheckDirectivesFn (core.es5.js:13121)
at Object.eval [as updateDirectives] (AdEditorComponent.html:48)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13106)
at checkAndUpdateView (core.es5.js:12288)

我测试了许多较小的情况,然后发现RendererAdapter在NgbRadio组件中包含有效的DebugRenderer2实例.

I tested many smaller cases then found the RendererAdapter encloses valid DebugRenderer2 instance in NgbRadio component.

因此,我对NgbRadio和NgbActiveLabel的构造函数进行了编写以进行测试,然后该应用程序运行正常:

So, I wrote a hack into the NgbRadio and NgbActiveLabel's constructor to test, then the application works fine:

this._renderer = _renderer.constructor.name === 'RendererAdapter'? _renderer.delegate: _renderer;

模板中的此结构会导致错误:

And this structure in the template makes the error:

<div [ngSwitch]="conditionalProperty">
  <my-component *ngSwitchCase="'case1'" ...></my-component>
  <my-another-comp *ngSwitchCase="'case2'" ...></my-another-comp>
</div>

让我列出该对话框可以在本地打开的两种情况:

Let me list two cases the dialog could open in my local:

  • 请勿在模板中具有ngSwitchCase属性的组件中注入任何管道依赖项(它们并不关心管道是我的自定义管道还是@ angular/common提供的管道)
  • 在ngSwitch div中只有一个组件(但可能包含其他具有ngSwitchCase的普通div)

我测试了Chrome,Safari和Firefox的最新版本,我的正式版本是4.2.4.

I tested the latest version of Chrome, Safari, and Firefox and my angular version is 4.2.4.

我从Google找不到任何有关RendererAdapter的有用文章. 我可能会使用上述技巧来解决此问题,但不想忽略真正的问题.我将不胜感激.

I couldn't find any useful article about RendererAdapter from Google. I might use above hack to solve this but don't want to ignore what was the real problem. I would appreciate any answers.

推荐答案

默认渲染器现在为 Renderer2 .因此,当您将渲染器注入组件时,应使用Renderer2令牌:

The default renderer now is Renderer2. So when you inject a renderer into a component you should use Renderer2 token:

class MyComponent {
   constructor(renderer: Renderer2)

但是,较早版本的Angular使用了 Renderer ,现在已弃用并将其注入Renderer使用了令牌:

However, earlier versions of Angular used Renderer which is now deprecated and to inject it Renderer token was used:

class MyComponent {
   constructor(renderer: Renderer)

RendererAdapter是一个将旧API映射到新API的类,例如,第一个渲染器具有listenGlobal方法,而后一个API使用listen.这是此特定方法的映射:

RendererAdapter is a class that maps old API to new API, for example, the first renderer had listenGlobal method, while the latter API uses listen. And here is the mapping for this specific method:

  listenGlobal(target: string, name: string, callback: Function): Function {
      return this.delegate.listen(target, name, <any>callback);
  }

其中委托是Renderer2的实例.

如果不使用Renderer注入令牌,则不会创建RendererAdapter. ngbRadio版本可能使用旧的渲染器.当前版本似乎正在使用新版本渲染器.

If you don't use Renderer injection token the RendererAdapter will not be created. It's possible that the version of ngbRadio uses old renderer. The current version seem to be using new renderer.

另请参见

  • https://github.com/angular/angular/issues/17558
  • https://github.com/angular/angular/issues/17378

这篇关于什么是RendererAdapter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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