如何公开公开角度2方法?

Jac*_*ャック 22 javascript angular

我目前正致力于将Backbone项目移植到Angular 2项目(显然有很多变化),其中一项项目要求需要某些方法可以公开访问.

一个简单的例子:

零件

@component({...})
class MyTest {
    private text:string = '';
    public setText(text:string) {
        this.text = text;
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,我可以<button (click)="setText('hello world')>Click me!</button>,我也想这样做.但是,我希望能够公开访问它.

像这样

<button onclick="angular.MyTest.setText('Hello from outside angular!')"></click>
Run Code Online (Sandbox Code Playgroud)

或这个

// in the js console
angular.MyTest.setText('Hello from outside angular!');
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,我希望该方法公开暴露,以便可以从angular 2应用程序外部调用它.

这是我们在骨干网上所做的事情,但我想我的Google foo不够强大,无法使用angular找到一个好的解决方案.

我们宁愿只公开一些方法并列出公共api,所以如果你有这方面的提示,那将是一个额外的奖励.(我有想法,但欢迎其他人.)

Gün*_*uer 24

只需使组件在全局映射中注册,您就可以从那里访问它.

使用构造函数或ngOnInit()任何其他生命周期钩子来注册组件并ngOnDestroy()取消注册它.

当您从Angular外部调用Angular方法时,Angular无法识别模型更改.这就是Angulars NgZone的用途.要获取对Angular区域的引用,只需将其注入构造函数即可

constructor(zone:NgZone) {
}
Run Code Online (Sandbox Code Playgroud)

您既可以使zone自己在全局对象中可用,也可以只执行区域内组件内的代码.

例如

calledFromOutside(newValue:String) {
  this.zone.run(() => {
    this.value = newValue;
  });
}
Run Code Online (Sandbox Code Playgroud)

或使用全局区域引用

zone.run(() => { component.calledFromOutside(newValue); });
Run Code Online (Sandbox Code Playgroud)

https://plnkr.co/edit/6gv2MbT4yzUhVUfv5u1b?p=preview

在浏览器控制台中,您必须切换到<topframe>,plunkerPreviewTarget....因为Plunker执行的代码iFrame.然后跑

window.angularComponentRef.zone.run(() => {window.angularComponentRef.component.callFromOutside('1');})
Run Code Online (Sandbox Code Playgroud)

要么

window.angularComponentRef.zone.run(() => {window.angularComponentRef.componentFn('2');})
Run Code Online (Sandbox Code Playgroud)


小智 16

这就是我做到的.我的组件如下.别忘了导入NgZone.这是最重要的部分.NgZone让角度理解外部环境.通过区域运行功能允许您从在Angular区域外执行的任务重新进入Angular区域.我们需要它,因为我们正在处理一个不在角区域内的外部呼叫.

 import { Component, Input , NgZone } from '@angular/core';
 import { Router } from '@angular/router';

    @Component({
        selector: 'example',
        templateUrl: './example.html',
    })
    export class ExampleComponent {
            public constructor(private zone: NgZone, private router: Router) {

//exposing component to the outside here
//componentFn called from outside and it in return calls callExampleFunction()
        window['angularComponentReference'] = {
            zone: this.zone,
            componentFn: (value) => this.callExampleFunction(value),
            component: this,
        };
    }

    public callExampleFunction(value: any): any {
        console.log('this works perfect');
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在让我们从外面调用它.在我的情况下,我想通过我的index.html.my index.html的脚本标签到达这里,如下所示.

<script>

//my listener to outside clicks
ipc.on('send-click-to-AT', (evt, entitlement) => 
electronClick(entitlement));;

//function invoked upon the outside click event

 function electronClick(entitlement){
//this is the important part.call the exposed function inside angular 
//component

    window.angularComponentReference.zone.run(() =
    {window.angularComponentReference.componentFn(entitlement);});
 }
</script>
Run Code Online (Sandbox Code Playgroud)

如果您只是在开发者控制台中键入以下内容并按Enter键,它将调用公开的方法,并且"这个工作完美"将打印在控制台上.

 window.angularComponentReference.zone.run(() =>
{window.angularComponentReference.componentFn(1);});
Run Code Online (Sandbox Code Playgroud)

权利只是作为参数传递的一些值.