简体   繁体   中英

how to access DOM elements in angular 4 service?

I am able to access DOM elements components like below

declare var jQuery: any;
declare var $: any;
//component stuff 
$('.my_class').innerHeight();

I am trying to implement the same inside the service class, but dom elements and template is not accessible in the service class.

ps: this is not duplicate of how to access them in components.

You can access DOM from an Angular service using the plain javascript document object, with some little additions to your service:

// We import not only "Injectable", but "Inject" too, from @angular/core
import { Injectable, Inject } from '@angular/core';
// We import DOCUMENT from @angular/common. Be careful, because the old import from '@angular/platform-browser' is deprecated.
import { DOCUMENT } from '@angular/common';

// Our standard service class in the usual way
@Injectable()
export class LoadingSpinnerService {

  // In the constructor we inject a dependency to DOCUMENT, of type HTMLDocument
  constructor(@Inject(DOCUMENT) private document: HTMLDocument) {     
    // We create a new div in the DOM, child of the body tag, <div id="LoadingSpinner"></div>
    var NewDomElement = this.document.createElement("div");
    NewDomElement.setAttribute("id", "LoadingSpinner");
    document.body.appendChild(NewDomElement);
  }
    
}

As you will probably know, you crete the service from the command line with something like:

ng g s loading-spinner

Don't forget to edit the app.module.ts to add the "import" to the service, and the item to the "providers" array in its "@NgModule" decorator:

import { LoadingSpinnerService } from './WHATEVER-DIRECTORY-YOU-CREATE-THE-SERVICE/loading-spinner.service';
(...)
providers: [LoadingSpinnerService, 
(...)

About the topic of using angular services only for data, i don't agree. As you can read in the official architecture guide for services:

https://angular.io/guide/architecture-services

Service is a broad category encompassing any value, function, or feature that an app needs.

A component can delegate certain tasks to services, such as fetching data from the server, validating user input, or logging directly to the console.

The provided example just in this documentation is for a log data service.

Hope this helps someone.

You can't in services. You can do it javascript way like document.getElementById .

In components and directives You can use ViewChild from @angular/core

HTML:

<div class="my_class" #myElement></div>

TS:

    import { ElementRef, ViewChild } from '@angular/core';


    @ViewChild('myElement') myElement:ElementRef;
console.log(this.myElement.nativeElement.offsetHeight); // inside any function.

I guess you cannot directly access with CSS selectors by Angular way. Alternatively, you can just use plain old JavaScript

document.getElementsByClassName("my-class");

Note: You can only do this in components and directives not inside services

Why Services

Components shouldn't fetch or save data directly and they certainly shouldn't knowingly present fake data. They should focus on presenting data and delegate data access to a service.

Source: https://angular.io/tutorial/toh-pt4

In Simpler terms:

  • component, directive for presenting, manipulating and interacting with DOM

  • services are for data handling between your component and backend

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM