繁体   English   中英

如何从独立的纯 JavaScript 函数调用 Angular 4 方法?

[英]How to call an Angular 4 method from a standalone plain JavaScript function?

我希望能够将一些数据\\传播事件从页面上的插件传递到我的 Angular 4 应用程序。

更具体地说,在我的情况下,数据\\事件是在页面上 Angular 应用程序旁边的 Silverlight 插件应用程序中生成的。

我有以下解决方案:

  • 创建一个从 Silverlight 调用的全局 JS 函数(因为这似乎是从 Silverlight 获取数据的最简单方法),以便在需要与 Angular 端对话时。
  • 反过来,该函数调用一些 Angular 类方法,传递从 Silverlight 收集的数据。

作为说明(不包括 Silverlight 部分),我们可以有以下内容。

作为 Angular 侧入口点的方法:

export class SomeAngularClass {
    public method(data: any): void {
        ...
    }
}

在 Angular 领域之外的某个地方,我们添加了一个全局纯 JavaScript 函数(由 Silverlight 调用):

window.somePlainJsFunction = function (data) {
    // How to consume SomeAngularClass.method() from here?
}

问题是:我们如何从一个普通的 JavaScript 函数调用 Angular 类方法?

正如@Dumpen 所指出的,您可以使用@HostListener 来获取从 Angular 之外的 javascript 调度的自定义事件。 如果您还想发送参数,则可以通过将它们添加为详细信息对象来发送它们。

在 JavaScript 中:

function dispatch(email, password) {
    var event = new CustomEvent('onLogin', {
        detail: {
            email: email,
            password: password
        }
    })
    window.dispatchEvent(event);
}

然后您可以在单击按钮时调用此方法。

现在要在 Angular 中收听这个调度事件,您可以在 Angular 组件中创建函数并将@HostListener 添加到它,如下所示:

@HostListener('window:onLogin', ['$event.detail'])
onLogin(detail) {
    console.log('login', detail);
}

您可以在任何组件中添加此代码。 我已将它添加到我的根组件 - AppComponent

您可以使用事件,这样您就可以让 JavaScript 发送您在服务中侦听的事件。

CustomEvent是一项新功能,因此您可能需要对其进行 polyfill: https : //developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent

JavaScript:

var event = new CustomEvent("CallAngularService");

window.dispatchEvent(event);

角度:

@HostListener("window:CallAngularService")
onCallAngularService() {
  // Run your service call here
}

我认为这就是您正在寻找的外角服务

您可以在 Angular 之外创建函数/类,并在 angular 中提供一个值。 通过这种方式,您可以同时处理有角和无角的东西:

class SomePlainClass {
  ...
}
window.somePlainJsFunction = new SomePlainClass();

@NgModule({
  providers: [{provide: SomePlainClass, useValue: window.somePlainJsFunction}],
  ...
})
class AppModule1 {}

@NgModule({
  providers: [{provide: SomePlainClass, useValue: window.somePlainJsFunction}],
  ...
})
class AppModule2 {}

class MyComponent {
  constructor(private zone:NgZone, private SomePlainClass:SharedService) {
    SomePlainClass.someObservable.subscribe(data => this.zone.run(() => {
      // event handler code here
    }));
  }
}

应该采取的方式取决于特定情况,尤其是优先级。

如果在 Angular 应用程序之前初始化 Silverlight 应用程序,并且在完成 Angular 应用程序初始化之前调用window.somePlainJsFunction ,这将导致竞争条件。 即使有一种可接受的方式从外部获取 Angular 提供程序实例,该实例在somePlainJsFunction调用期间也不存在。

如果Angular 引导程序之后调用window.somePlainJsFunction回调,则应Angular 应用程序内部分配window.somePlainJsFunction ,其中SomeAngularClass提供程序实例可访问:

window.somePlainJsFunction = function (data) {
    SomeAngularClass.method();
}

如果Angular 引导程序之前调用window.somePlainJsFunction回调,它应该为 Angular 应用程序提供全局数据以获取:

window.somePlainJsFunction = function (data) {
    window.angularGlobalData = data;
}

然后window.angularGlobalData可以在 Angular 中直接使用或作为提供者使用。

工作示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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