简体   繁体   English

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

[英]How to expose angular 2 methods publicly?

I am currently working on porting a Backbone project to an Angular 2 project (obviously with a lot of changes), and one of the project requirements requires certain methods to be accessible publicly. 我目前正致力于将Backbone项目移植到Angular 2项目(显然有很多变化),其中一项项目要求需要某些方法可以公开访问。

A quick example: 一个简单的例子:

Component 零件

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

Obviously, I could have <button (click)="setText('hello world')>Click me!</button> , and I would want to do that as well. However, I'd like to be able to access it publicly. 显然,我可以有<button (click)="setText('hello world')>Click me!</button> ,我也希望这样做。但是,我希望能够访问它公开。

Like this 像这样

<button onclick="angular.MyTest.setText('Hello from outside angular!')"></click>

Or this 或这个

// in the js console
angular.MyTest.setText('Hello from outside angular!');

Either way, I would like the method to be publicly exposed so it can be called from outside the angular 2 app. 无论哪种方式,我希望该方法公开暴露,以便可以从angular 2应用程序外部调用它。

This is something we've done in backbone, but I guess my Google foo isn't strong enough to find a good solution for this using angular. 这是我们在骨干网上所做的事情,但我想我的Google foo不够强大,无法使用angular找到一个好的解决方案。

We would prefer to only expose some methods and have a list of public apis, so if you have tips for doing that as well, it'd be an added bonus. 我们宁愿只公开一些方法并列出公共api,所以如果你有这方面的提示,那将是一个额外的奖励。 (I have ideas, but others are welcomed.) (我有想法,但欢迎其他人。)

Just make the component register itself in a global map and you can access it from there. 只需使组件在全局映射中注册,您就可以从那里访问它。

Use either the constructor or ngOnInit() or any of the other lifecycle hooks to register the component and ngOnDestroy() to unregister it. 使用构造函数或ngOnInit()或任何其他生命周期钩子来注册组件,使用ngOnDestroy()来注销它。

When you call Angular methods from outside Angular, Angular doesn't recognize model change. 当您从Angular外部调用Angular方法时,Angular无法识别模型更改。 This is what Angulars NgZone is for. 这就是Angulars NgZone的用途。 To get a reference to Angular zone just inject it to the constructor 要获取对Angular区域的引用,只需将其注入构造函数即可

constructor(zone:NgZone) {
}

You can either make zone itself available in a global object as well or just execute the code inside the component within the zone. 您既可以在全局对象中使zone本身可用,也可以只在区域内的组件内执行代码。

For example 例如

calledFromOutside(newValue:String) {
  this.zone.run(() => {
    this.value = newValue;
  });
}

or use the global zone reference like 或使用全局区域引用

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

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

In the browser console you have to switch from <topframe> to plunkerPreviewTarget.... because Plunker executes the code in an iFrame . 在浏览器控制台中,您必须从<topframe>切换到plunkerPreviewTarget....因为Plunker在iFrame执行代码。 Then run 然后跑

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

or 要么

window.angularComponentRef.zone.run(() => {window.angularComponentRef.componentFn('2');})

This is how i did it. 这就是我做到的。 My component is given below. 我的组件如下。 Don't forget to import NgZone. 别忘了导入NgZone。 It is the most important part here. 这是最重要的部分。 It's NgZone that lets angular understand outside external context. NgZone让角度理解外部环境。 Running functions via zone allows you to reenter Angular zone from a task that was executed outside of the Angular zone. 通过区域运行功能允许您从在Angular区域外执行的任务重新进入Angular区域。 We need it here since we are dealing with an outside call that's not in angular zone. 我们需要它,因为我们正处理一个不在角区域内的外部呼叫。

 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');
        }
    }

now lets call this from outside.in my case i wanted to reach here through the script tags of my index.html.my index.html is given below. 现在让我们从外面调用它。在我的情况下,我想通过我的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>

if you just type the below in developer console and hit enter it will invoke the exposed method and 'this works perfect ' will be printed on console. 如果您只是在开发者控制台中键入以下内容并按Enter键,它将调用公开的方法,并且“这个工作完美”将打印在控制台上。

 window.angularComponentReference.zone.run(() =>
{window.angularComponentReference.componentFn(1);});

entitlement is just some value that is passed here as a parameter. 权利只是作为参数传递的一些值。

I was checking the code, and I have faced that the Zone is not probably necessary. 我正在检查代码,我已经面临区域可能不是必需的。 It works well without the NgZone. 没有NgZone,它运作良好。

In component constructor do this: 在组件构造函数中执行此操作:

constructor(....) {
   window['fncIdentifierCompRef'] = {
      component  = this
   };
}

And in the root script try 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>

This works to me. 这对我有用。

The problem is that Angular's components are transpiled into modules that aren't as easy to access as regular JavaScript code. 问题是Angular的组件被转换为不像常规JavaScript代码那样容易访问的模块。 The process of accessing a module's features depends on the module's format. 访问模块功能的过程取决于模块的格式。

An Angular2 class can contain static members that can be defined without instantiating a new object. Angular2类可以包含可以在不实例化新对象的情况下定义的静态成员。 You might want to change your code to something like: 您可能希望将代码更改为:

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

Super simple solution!! 超简单解决方案!! save component or function with an alias outside 使用外部别名保存组件或功能

declare var exposedFunction;
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
    constructor(public service:MyService){
    exposedFunction = service.myFunction;
}

at index.html add in head 在index.html添加头部

<script>
    var exposedFunction;
</script>

Inside exposed function do not use this. 内部曝光功能不使用此功能。 parameters if you need them you will have to use closures to get it to work 参数如果你需要它们,你将不得不使用闭包来使它工作

This is particularly useful in ionic to test device notifications on web instead of device 这在离子测试设备通知上特别有用,而不是设备

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

相关问题 如何在JS中公开成员变量的公共方法 - how to expose public methods of member variables in JS 如何公开属性对象的方法,就像它们是对象自己的方法一样? 的JavaScript - How to expose methods of a property object as if they are objects own methods? JavaScript 如何在Angular应用程序中暴露package.json - How to expose package.json in angular app 如何公开React类的状态或任何方法? - How can I expose the state or any of the methods of a React class? 初始化后如何扩展JavaScript对象/函数以公开API方法? - How to extend a JavaScript object/function to expose API methods after initialization? 如何将jQuery本机/本地范围公开给变量以扩展对象方法 - How to expose jQuery native / local scope to variables to extend object methods 在WKWebView中用JavaScript公开本机方法 - Expose native methods in JavaScript in WKWebView 如何在 Angular 中将子组件的 @inputs 和 @outputs 隐式公开给祖父母? - How to expose child component's @inputs and @outputs implicitly to grandparent in Angular? 如何在Angular JS中将服务中的值公开给HTML - How to expose a value from Service to the HTML in Angular JS 如何在子指令中评估Angular表达式并在父指令中公开它? - How to evaluate Angular expression in child directive and expose it on parent directive?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM