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

时间:2017-09-08 16:25:47

标签: javascript angular dependency-injection

我希望能够将一些数据\传播事件从页面上的插件传递到我的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类方法?

4 个答案:

答案 0 :(得分:2)

您可以使用活动,因此您可以让JavaScript发送您正在服务中收听的活动。

CustomEvent 是一项新功能,因此您可能需要对其进行填充: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
}

答案 1 :(得分:1)

我认为这就是你要找的service out side 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
    }));
  }
}

答案 2 :(得分:1)

应该采取的方式取决于具体情况,尤其是优先顺序。

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

如果在 Angular bootstrap之后调用 ,则应在 Angular应用程序中分配 window.somePlainJsFunction,其中window.somePlainJsFunction提供程序实例可以到达:

SomeAngularClass

如果在 Angular bootstrap之前调用了window.somePlainJsFunction = function (data) { SomeAngularClass.method(); } 回调,它应该为Angular应用程序提供全局数据:

window.somePlainJsFunction

然后window.somePlainJsFunction = function (data) { window.angularGlobalData = data; } 可以在Angular中直接使用,也可以作为提供者使用。

Working Example

答案 3 :(得分:0)

正如@Dumpen指出的那样,您可以使用@HostListener来获取从Angular外部的javascript调度的自定义事件。如果还希望发送参数,则可以通过将它们添加为 detail 对象的方式来发送它们。

在Java语言中:

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