如何使一个组件在Angular2皆可访问 [英] How to make a component universally accessible in Angular2

查看:137
本文介绍了如何使一个组件在Angular2皆可访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我基本上要创建我可以从任何地方在我Angular2应用程序利用无论在哪里使用的组件是在应用程序树自定义对话框组件。为简单起见让我们称之为这是我的SayHello组件。

考虑下面的应用程序树:

因此​​,让我们说,我想的 SomeComponent.level3.component ,调出的 SayHello.component 对话框。

在角1.x中我会注入到RootScope控制器,照亮一个对话框的方式。现在,我明白了(或多或少),对于Angular2你可以泡事件(与事件发射器)了组件树,但它似乎很乏味的泡沫事件从SomeComponent.level3.component了树一路下来的SayHello 。零件。

所以我想我会创造一个SayHello的服务,我想照亮我的对话我会在任何地方注入。这里是code我已经制定了一个草图。

myApp.component.ts

\r
\r

从&LT进口{SayHelloComponent};<文件夹>> / sayHello的。零件;\r
从进口{} BunchOfComponents<<&夹GT;> / bunchOfComponents\r
\r
@零件({\r
    指令:[SayHelloComponent]\r
    选择:我的应用,\r
    templateUrl:`<一堆-OF-成分>在此组件中存在\r
                      一堆-OF-成分&gt /; SomeComponent.level3.component<\r
                      <再说问候的ShowDialog ={{}的ShowDialog}消息={{消息}}>\r
                      < /说问候>`\r
\r
})\r
出口类myAppComponent {\r
    的ShowDialog = FALSE;\r
    消息=;\r
\r
    构造函数(私人sayHelloService:SayHelloService){\r
        this.showDialog = sayHelloService.showDialog;\r
        this.message = sayHelloService.message;\r
\r
    }\r
}

\r

\r
\r

SayHelloService.ts

\r
\r

进口{}注射从'angular2 /核心;\r
\r
@Injectable()\r
出口类SayHelloService {\r
    公众的ShowDialog:布尔= FALSE;\r
    公开消息:字符串=;\r
\r
    构造函数(){\r
\r
    }\r
\r
}

\r

\r
\r

SayHello.component.ts

\r
\r

进口{}组件从angular2 /芯;\r
进口{} SayHelloService从<<&夹GT;> / SayHelloService\r
@零件({\r
    指令:[],\r
    选择:说,你好,\r
    模板:[做你好组件]\r
})\r
出口类SayHelloComponent {\r
    @input()ShowDialog的:布尔;\r
    @input()消息:字符串;\r
\r
       构造函数(私人sayHelloService:SayHelloService){\r
\r
    }\r
    //这里这样的想法是在的ShowDialog检测到变化\r
    //如果为真,那么做一个警报消息\r
    ngOnChanges(变化:{[作为propName:字符串]:SimpleChange}){\r
        VAR OBJ =修改[的ShowDialog];\r
        如果(OBJ!== NULL){\r
            如果(修改[ShowDialog的。CurrentValue的===真){\r
                警报(this.message);\r
                this.sayHelloService.showDialog = FALSE;\r
            }\r
\r
        };\r
    }\r
\r
}

\r

\r
\r

SomeComponent.level3.component

\r
\r

进口{}组件从angular2 /芯;\r
进口{} SayHelloService从<<&夹GT;> / SayelloService\r
\r
@零件({\r
    指令:[],\r
    选择:一些组件\r
    模板:<按钮(点击)='doHello()'>不要打招呼< /按钮>中\r
})\r
出口类PageContactUsComponent {\r
\r
    构造函数(私人sayHelloService:SayHelloService){\r
\r
    }\r
\r
\r
    doHello(){无效\r
        this.sayHelloService.message =Hello World的;\r
        this.sayHelloService.showDialog = TRUE;\r
    }\r
}

\r

\r
\rappBoot.ts

\r
\r

进口{}引导从angular2 /平台/浏览器;\r
从进口{} MyAppComponent<<&夹GT; / MyAppComponent\r
进口{} SayHelloService从<<&夹GT;> / SayHelloService\r
\r
引导(MyAppComponent,[\r
    SayHelloService\r
]);

\r

\r
\r

不用说,这是行不通的。我没有得到任何错误,但SayHello.component不检测的ShowDialog'的值的任何变化......所以什么也不会发生。任何想法如何正确地做这样做会大大AP preciated。


解决方案

作为评论上面提到的,


  • 把一个EventEmitter里面的服务。

  • 放在其它组件可以调用服务的ShowDialog()API /方法。 ShowDialog的()方法应该发出()的事件。

  • 您的对话框组件可以订阅该事件,并取消隐藏/显示自己当它收到一个事件。

要包装在服务上的EventEmitter,请参阅this回答

I basically want to create a custom dialog component that I can utilize from anywhere in my Angular2 app regardless of where the using component is in the application tree. For simplicity lets call this my SayHello Component.

Consider the following application tree:

So let's say i want SomeComponent.level3.component to call up the dialog in SayHello.component.

In Angular 1.x I would inject RootScope into a controller and light up a dialog that way. Now, I understand (more or less) that for Angular2 you can bubble events (with event emitters) up the component tree, but it seems tedious to bubble an event all the way from SomeComponent.level3.component up the tree and down to SayHello.component.

So I thought I would create a SayHello Service that I would inject anywhere I wanted to light up my dialog. Here is a sketch of the code I have formulated.

myApp.component.ts

import {SayHelloComponent} from "<<folder>>/sayHello.component";
import {BunchOfComponents} from "<<folder>>/bunchOfComponents";

@Component({
    directives: [SayHelloComponent],
    selector: "my-app",
    templateUrl: `<bunch-of-components>Within this component exists
                      SomeComponent.level3.component </bunch-of-components>
                      <say-hello showdialog="{{showDialog}}" message="{{message}}">
                      </say-hello>`

})
export class myAppComponent {
    showDialog = false;
    message = "";

    constructor(private sayHelloService: SayHelloService) {
        this.showDialog = sayHelloService.showDialog;
        this.message = sayHelloService.message;

    }
}

SayHelloService.ts

import {Injectable} from 'angular2/core';

@Injectable()
export class SayHelloService {
    public showDialog: boolean = false;
    public message: string ="";

    constructor() {

    }

}

SayHello.component.ts

import {Component} from "angular2/core";
import {SayHelloService} from "<<folder>>/SayHelloService";
@Component({
    directives: [],
    selector: "say-hello",
    template: "[do hello component]"
})
export class SayHelloComponent {
    @Input() showdialog: boolean;
    @Input() message: string;

       constructor(private sayHelloService: SayHelloService) {

    }
    //This idea here is to detect change in showDialog
    //If true then do an alert with the message
    ngOnChanges(changes: { [propName: string]: SimpleChange }) {
        var obj = changes["showdialog"];
        if (obj !== null) {
            if (changes["showdialog"].currentValue === true) {
                alert(this.message);
                this.sayHelloService.showDialog = false;
            }

        };
    }

}

SomeComponent.level3.component

import {Component} from "angular2/core";
import {SayHelloService} from "<<folder>>/SayelloService";

@Component({
    directives: [],
    selector: "some-component",
    template: "<button (click)='doHello()'>Do say hello</button>"
})
export class PageContactUsComponent {

    constructor(private sayHelloService: SayHelloService) {

    }


    doHello(): void {
        this.sayHelloService.message = "Hello world";
        this.sayHelloService.showDialog = true;
    }
}

appBoot.ts

import {bootstrap} from "angular2/platform/browser";
import {MyAppComponent} from "<<folder>/MyAppComponent";
import {SayHelloService} from "<<folder>>/SayHelloService";

bootstrap(MyAppComponent, [
    SayHelloService
]);

Needless to say, this doesn't work. I don't get any errors, but the SayHello.component does not detect any change in the value of 'showdialog'...so nothing happens. Any ideas as to how to do properly do this would be much appreciated.

解决方案

As mentioned in a comment above,

  • Put an EventEmitter inside the service.
  • Put a showDialog() API/method on the service that other components can call. The showDialog() method should emit() an event.
  • Your dialog component can subscribe to the event and unhide/show itself when it receives an event.

To wrap an EventEmitter in a service, see this answer.

这篇关于如何使一个组件在Angular2皆可访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆