问题
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)
I tested many smaller cases then found the RendererAdapter encloses valid DebugRenderer2 instance in NgbRadio component.
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:
- Do not inject any pipe dependency (they don't care the pipes are my custom or provided from @angular/common) into the components has ngSwitchCase attribute at the template
- Only one component in the ngSwitch div (but could contains other normal divs have ngSwitchCase)
I tested the latest version of Chrome, Safari, and Firefox and my angular version is 4.2.4.
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.
回答1:
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)
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
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);
}
where delegate is an instance of Renderer2
.
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.
See also
- https://github.com/angular/angular/issues/17558
- https://github.com/angular/angular/issues/17378
来源:https://stackoverflow.com/questions/44792622/what-is-the-rendereradapter