angular: [4.x Cleanup] Remove Renderer.invokeElementMethod, as Angular does not use it!

The invokeElementMethod of the renderer is not used in Angular.

It should be removed in the 4.x branch

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 18 (7 by maintainers)

Most upvoted comments

Wouldn’t this break people apps (I know the 4.x is for the breaking changes, but this may be too much imo)? I mean, if you google “renderer invokeElementMethod” you’ll get a lot of results. It’s even recommended in @kara’s Angular 5 rookie mistakes under Solution: ViewChild + local template variable. It may not be used internally by angular, but people use it to not access the DOM directly. If the method gets removed, what would be the alternative?

Should the documentation be updated to give people a clear direction upgrading from v2 to v4 who use invokeElementMethod?

 this.renderer.invokeElementMethod(this.inputElement.nativeElement, 'focus');

Got focus on input field to work with Angular 4.1.0 and Renderer2. It appears to work like jQuery selector this.renderer.selectRootElement(#myInput’).

The input field has an id=“myInput”. Not sure the slide-out approach is the best UI. After you do get focus on the field and you close it you really need to then put back the focus where you originated. It’s an experiment. From what I understand Ionic framework uses a push on the router so it’s like stacking up the page so when you go back you are where you left off. It would be nice if we could do the same. On older Angular where it was OK to use the DOM we could store the previous focus element via document.activeElement and then return focus. It would be great if there was a best practice on this for accessibility and some advanced types of animated panels. Focus worked for me using the following in a setTimeout.
let onElement = this.renderer.selectRootElement(‘#myInput’); onElement.focus();

@DzmitryShylovich @vicb has to tell us what’s the proper way to do it without accesing nativeElement 😄

Do you mean you own render service or what service, how to register this service? Do you have any example of such service? I feel this is so common use case that the framework should provide a solution and we had it in Angular 2.

This custom service can help someone:

import { Injectable, PLATFORM_ID, Inject, ElementRef } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

@Injectable()
export class MyRenderer {

  constructor(
    @Inject(PLATFORM_ID) private platformId: Object
  ) { }

  invokeElementMethod(eleRef: ElementRef, method: string) {
    if (isPlatformBrowser(this.platformId)) {
      eleRef.nativeElement[method]();
    }
  }
}

@ipassynk and @MatteoNY it is ok to use DOM API directly if you 100% sure your app will never run outside browser (DOM environment). Advice to not use DOM is overmarketed.

@ipassynk to have a focus you don’t need to recreate the whole renderer. You can create 2 services with method focus(el: any): void { ... } . 1st will recreate logic using DOM api, 2nd service will have an empty method. Then you provide service with the DOM API to the application that is run in the browser, and you provide service with the empty method for the application that run in other environment (server?).

So that you have main.browser.ts, main.node.ts, OR environments.ts. Or any other approach that lets you separate services for different environments. Meanwhile code of the rest of you application is the same.