简体   繁体   中英

How to make service in angular 2+ accessible in javascript

I have the following scenario.

I have a simple angular 2 app with a service which I add to providers in app.module. When I click on a button the app should load a javascript file and execute a function eg function A defined in this javascript file. So the question is how can I access the service within this function A. My consideration is to append the service to the global window variable. Are there better ways to achieve it?

Code:

export class MyService{
    public editProjectDone = new Subject<string>();
}

app.module.ts
{
    ...providers: [MyService]
}

app.component.html
<button (click)="editProject()">Edit project</button>

app.component.ts
function editProject(){
    ... load Javascript file
    call javascript file
    js.editProject("projectId") // call function defined in javascript file
}

javascript file
{
    function editProject(projectId)
    {
        //do calculation 
        // fire event that calculation is done
        // the calcuation is not done in typescript, but here
        MyService.editProjectDone.next() 
        // The question is here how to access the event and fire it
    }
}

So you want to access angular service method in javascript function A() .

For example:

Your service class:

export class SettingsService{
    getLanguage() {
        return 'en-GB';
    }
}

Your javascript file

function A() {
    settingsService.getLanguage();
}

Solution: Custom Event .

Basically you define a custom event handler in javascript file. And define the Custom Event and dispatchEvent the Custom Event in Angular click event function.

app.component.html:

<input type="button" value='log' (click)="logclick($event)">

app.component.ts

constructor(private settings: SettingsService){}

logclick(event){
    // define custom event
    var customevent = new CustomEvent(
    "newMessage", 
    {
        detail: {
            message: "Hello World!",
            time: new Date(),
            myservice: this.settings //passing SettingsService reference
        },
        bubbles: true,
        cancelable: true
      }
    );
    event.target.dispatchEvent(customevent); //dispatch custom event
}

javascript file:

// event handler function
function newMessageHandler(e) {
    console.log(
        "Event subscriber on "+e.currentTarget.nodeName+", "
        +e.detail.time.toLocaleString()+": "+e.detail.message
    );
    //calling SettingsService.getLanguage()
    console.log(e.detail.myservice.getLanguage());
}
//adding listener to custom event.
document.addEventListener("newMessage", newMessageHandler, false);

Example output:

Event subscriber on #document, 9/11/2018, 11:31:36 AM: Hello World!
en-GB

Note: I have not added section for dynamically loading javascript file. I assume you are already able to do that from your comments.

Declare variable as public using window object but in proper way. export only some functions not whole service and in some standard way like below.

In Angular

export class AbcService {
  constructor() {
    const exportFunctions = {
      xyzFunction: this.xyzFunction.bind(this),
      pqrFunction: this.pqrFunction.bind(this)
    }; // must use .bind(this)
    window['ngLib']['abcService'] = exportFunctions;
  }

  xyzFunction(param1, param2) {
    // code
  }

  pqrFunction() {
    // code
  }

  private oneFunction() {
    // code
  }

  private twoFunction() {
    // code
  }
}

In Javascript

ngLib.abcService.xyzFunction(value1, value2);
ngLib.abcService.pqrFunction();

You have to use service variable to access functions and variable of particular services.

Here I demonstrate how you can do it.

export class AppComponent  {
  name = 'Angular';
  constructor(private myServices: MyServices){
     this.myServices.sayHello();
  }
}

Whole code available here : https://stackblitz.com/edit/angular-services-example

Firstly you need to import the js file before calling the service and that can be done by:

TS

let js: any = require('JSFileNAME')['default']; //Something lik this in constructer

then once the file is imported you need to create a instantiate of the js in your Ts something like

this.newObjectOfJs = new js(); // pass any paramater if its required.

hereafter you will be able to access the methods and service from the JSfile.

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