Javascript 如何公开angular 2方法?

Javascript 如何公开angular 2方法?,javascript,angular,Javascript,Angular,我目前正在将一个主干项目移植到Angular 2项目(显然有很多更改),其中一个项目需求要求某些方法可以公开访问 一个简单的例子: 组件 @component({...}) class MyTest { private text:string = ''; public setText(text:string) { this.text = text; } } 显然,我可以让只需将组件注册到全局映射中,您就可以从那里访问它 使用构造函数或ngOnInit()

我目前正在将一个主干项目移植到Angular 2项目(显然有很多更改),其中一个项目需求要求某些方法可以公开访问

一个简单的例子:

组件

@component({...})
class MyTest {
    private text:string = '';
    public setText(text:string) {
        this.text = text;
    }
}

显然,我可以让
只需将组件注册到全局映射中,您就可以从那里访问它

使用构造函数或
ngOnInit()
或任何其他方法注册组件,并使用
ngondstroy()
取消注册组件

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

constructor(zone:NgZone) {
}
您可以使
zone
本身在全局对象中也可用,也可以仅在分区内的组件内执行代码

比如说

calledFromOutside(newValue:String) {
  this.zone.run(() => {
    this.value = newValue;
  });
}
或者使用全局区域参照,如

zone.run(() => { component.calledFromOutside(newValue); });

在浏览器控制台中,您必须从
切换到
plunkerPreviewTarget…
,因为Plunker在
iFrame
中执行代码。然后跑

window.angularComponentRef.zone.run(() => {window.angularComponentRef.component.callFromOutside('1');})


问题是Angular的组件被传输到模块中,这些模块不像常规JavaScript代码那样容易访问。访问模块功能的过程取决于模块的格式

Angular2类可以包含静态成员,这些成员可以在不实例化新对象的情况下定义。您可能希望将代码更改为以下内容:

@component({...})
class MyTest {
    private static text: string = '';
    public static setText(text:string) {
        this.text = text;
    }
}

我就是这样做的。下面给出了我的组件。别忘了导入NgZone。这是这里最重要的部分。NgZone让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');
        }
    }
现在让我们从外部调用它。在我的例子中,我想通过我的index.html的脚本标记到达这里。下面给出了我的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>

权限只是作为参数传递到此处的某个值。

我正在检查代码,并且我遇到了可能不需要区域的情况。 它在没有NgZone的情况下运行良好

在组件构造函数中,执行以下操作:

constructor(....) {
   window['fncIdentifierCompRef'] = {
      component  = this
   };
}
在根脚本中,尝试以下操作:

<script>
function theGlobalJavascriptFnc(value) {
  try {
    if (!window.fncIdentifierCompRef) {
      alert('No window.fncIdentifierCompRef);
      return;
    }
    if (!window.fncIdentifierCompRef.component) {
      alert('No window.fncIdentifierCompRef.component');
      return;
    }  
    window.fncIdentifierCompRef.component.PublicCmpFunc(value);
  } catch(ex) {alert('Error on Cmp.PublicCmpFunc Method Call')}  
}
</script>

函数theGlobalJavascriptFnc(值){
试一试{
如果(!window.fncIdentifierCompRef){
警报('No window.fncIdentifierCompRef);
返回;
}
如果(!window.fncIdentifierCompRef.component){
警报('No window.fncIdentifierCompRef.component');
返回;
}  
window.fncIdentifierCompRef.component.PublicCmpFunc(值);
}catch(ex){alert('Cmp.PublicCmpFunc方法调用时出错')}
}

这对我很有用。

超级简单的解决方案!!使用外部别名保存组件或函数

declare var exposedFunction;
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
    constructor(public service:MyService){
    exposedFunction = service.myFunction;
}
在index.html加载项头部

<script>
    var exposedFunction;
</script>

var暴露函数;
内部公开函数不使用此选项。如果需要参数,则必须使用闭包才能使其工作


这在ionic中特别有用,可以在web上测试设备通知,而不是设备

Ok,因此我需要为我的所有公共方法创建helper方法。非常感谢您的帮助,顺便说一句。因此,在创建注册任务的服务时,我遇到了与开始使用
zone.run(()=>{})之前相同的问题。
该方法已注册,我可以毫无问题地调用它,但是,似乎没有运行更改检测<代码>window.widget[name]=()=>{window.zone.run(()=>{scope[callbackMethod]();});}
scope
是组件,我调用的方法是
callbackMethod
。有什么提示吗?我很欣赏plunkr,但问题是我有一个外部服务正在window.widget对象上添加该方法。我可以调用这些方法,但是变化检测没有启动。看起来您的示例包含了我在不使用外部服务时使用的内容。(我可能会放弃那个外部服务。)谢谢你的帮助。现在angular也不例外,所以ngZone不适用于这个场景,对吗?否则我的假设就错了?@k11k2我不知道razor页面是什么,也不知道它们如何与NgZone相关。我还需要一种公开组件的方法吗?要访问Angular之外的组件,你应该看看transpiled JavaScript。通常,web页面通过访问加载程序加载组件(请参见
System.import
at)。默认情况下,通过systemjs加载的组件不可访问,查看传输的js也没有帮助,因为js正在使用System.register加载。Angular(或Angular等)甚至在全局范围内都不可用,()并且我们不会在生产中使用systemjs。可能是@DaveKennedy的副本。您知道这个问题是在发布之前发布的,对吗?我刚刚按照你的步骤完成了
无法读取未定义的属性“zone”
这发生在
home.cshtml中的
ClickEvent
我的函数看起来像
函数ClickEvent(){window.angularComponentReference.zone.run(()=>{window.angularComponentReference.component.ClickEvents();})}
ps:在开发者控制台中,它工作正常。您是否将Ngzone导入到您的组件中?小心!!使用
()=>{}
在angular外部公开函数将不适用于IE。angular不会传输该函数。你应该使用
function(){}
我已经投了赞成票,因为你的答案比公认的答案清楚得多。我需要什么区域,我可以直接调用window.angularComponentReference.componentFn(权利)。它起作用了?那么如何从android调用它呢?同样,只需将它添加到web文件@mohammadrzamrg、index.html和您公开的函数中即可
constructor(....) {
   window['fncIdentifierCompRef'] = {
      component  = this
   };
}
<script>
function theGlobalJavascriptFnc(value) {
  try {
    if (!window.fncIdentifierCompRef) {
      alert('No window.fncIdentifierCompRef);
      return;
    }
    if (!window.fncIdentifierCompRef.component) {
      alert('No window.fncIdentifierCompRef.component');
      return;
    }  
    window.fncIdentifierCompRef.component.PublicCmpFunc(value);
  } catch(ex) {alert('Error on Cmp.PublicCmpFunc Method Call')}  
}
</script>
declare var exposedFunction;
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
    constructor(public service:MyService){
    exposedFunction = service.myFunction;
}
<script>
    var exposedFunction;
</script>