什么是渲染器适配器?

What is the RendererAdapter?

虽然我无法重现问题,但请看看我的 plunker

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

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 实例。

所以,我写了一个 hack 到 NgbRadio 和 NgbActiveLabel 的构造函数中进行测试,然后应用程序工作正常:

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

而模板中的这个结构出错:

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

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

我测试了最新版本的 Chrome、Safari 和 Firefox,我的 angular 版本是 4.2.4。

我在 Google 中找不到任何关于 RendererAdapter 的有用文章。 我可能会使用上面的 hack 来解决这个问题,但不想忽略真正的问题。如果有任何答案,我将不胜感激。

现在的默认渲染器是 Renderer2。因此,当您将渲染器注入组件时,您应该使用 Renderer2 token:

class MyComponent {
   constructor(renderer: Renderer2)

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

class MyComponent {
   constructor(renderer: Renderer)

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

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

其中委托是 Renderer2 的一个实例。

如果您不使用 Renderer 注入令牌,则不会创建 RendererAdapterngbRadio 的版本可能使用旧的渲染器。当前版本 seem to be using new renderer.

另见