簡體   English   中英

Angular2,應用程序內所有其他組件的通用覆蓋組件

[英]Angular2, generic overlay component for all other components inside the app

我有以下兩個組成部分:

覆蓋

@Component({
    selector: 'overlay',
    template: '<div class="check"><ng-content></ng-content></div>'
})
export class Overlay {
    save(params) {
        //bunch of stuff that are commonly used
    }
}

myComponent(還有很多這樣的)

@Component({
    selector: 'myComponent',
    directives: [Overlay],
    template: '<overlay><form (ngSubmit)="save({ name: 'sam', lastName: 'jones' })">I'm the component. Click <input type="submit">Here</input> to save me!</form></overlay>'
})
export class MyComponent {

}

沒有拋出錯誤,這個解決方案不起作用,Angular2只是跳過兩個組件初始化。 無論如何,我想你在這里得到了這個想法。 有一個共同的組件需要包裝許多其他組件,因此它需要是通用的。 它有一個template所以服務不能完成這項工作。 我沒有使用自定義注釋,也許他們可以做這樣的事情? 有關如何實現這種功能的任何想法?

注意:疊加層包含邏輯和模板,這些都是需要使用它的任何其他組件所需要的。 模板是一個復雜的模態對話框,包含動畫,消息,淡入淡出等......這在整個解決方案中很常見。

更新

發現這個: Angular2:progress / loading overlay指令

好吧也許這不是你的問題的直接答案,但從你的評論我想你想在你的應用程序中實現模態。 我還沒有完成它 ,但在不久的將來我會(這是我應用程序要求的一部分)。

首先我不使用bootstrap javascript,因為我已經使用了角度。 你唯一需要的是bootstrap css

考慮以下根模板:

 <my-app></my-app>

 <my-modal>
    <div class="modal-container">
       <div class="modal-content">{{modalContent}}</div>
    </div>
 </my-modal>

展示你的模態:全球事件

您可以從任何component顯示模態。 訣竅是注入modal-service來發送全局事件 看到這個答案,看看它是如何工作的。

您可以將任何對象作為event發送。 此事件對象可能包含模態的內容或key因此模態component可以從其他位置獲取它。

ModalComponent

您的ModalComponent應訂閱該事件。 在事件中,您可以通過幾種方式顯示和隱藏它(模態組件),我確信您已經知道。 使用結構指令是一種方法。

樣式

模態是一個容器( .modal-container ),具有透明背景的視口 widthheight Modal的內容( .modal-content )是另一個具有固定widthheight以及absolute位置的容器。 如果您想要自舉樣式,可以添加它,對於動畫,您可以使用角度動畫

我目前正在使用類似的方法進行菜單欄,它的效果非常好!!

我為這個特定的任務創建了一個,並考慮將bootstrap模式嵌入作為模板,但遇到了一些問題,例如,bootstrap模式中唯一有用的部分是類名。 毫不奇怪,因為我需要區分窗口模態和組件上的進度模態,所以不希望這個特定的任務。

覆蓋

@Component({
    selector: 'overlay',
    template:
    `<div [ngClass]="isOpen ? 'opened' : 'closed'">
         <div class="modal" role="dialog">
            <div class="modalBody">
                <div *ngIf="isSaving">
                    <span class="text-success text-bold">
                        Saving...
                    </span>
                </div>
                <div *ngIf="isSaved">
                    <span class="text-success text-bold">
                        Saved.
                    </span>
                </div>
            </div>
        </div>
    </div>`,
    styles: [
        '.modal { position:absolute; width: 100%; height: 100%; margin: -30px; background-color: rgba(255, 255, 255, 0.7); z-index: 1000; text-align: center; }',
        '.closed { visibility: hidden; }',
        '.opened { visibility: visible; }',
        '.modalBody { top: 45%; left: 25%; width: 50%; position: absolute; }',
        '.text-bold { font-weight: 800; font-size: 1.5em; }'
    ]
})
export class Overlay implements OnChanges, AfterContentInit {
    @Input() isSaving: boolean = false;
    @Input() isSaved: boolean = false;
    @Input() containerElement: HTMLElement;

    isOpen = false;

    private modalElement;

    constructor(private element: ElementRef, private animationBuilder: AnimationBuilder) { }

    ngOnChanges() {
        if (this.modalElement) {
            if (this.isSaving == true || this.isSaved == true) {
                this.toggleAnimation(true);
            }
            else if (this.isSaving == false && this.isSaved == false) {
                this.toggleAnimation(false);
            }
        }
    }

    ngAfterContentInit() {
        this.containerElement.style.position = 'relative';
        this.modalElement = this.element.nativeElement.querySelector('.modal');
    }

    private toggleAnimation(isOpen) {
        var startCss = { backgroundColor: 'rgba(255, 255, 255, 0)' };
        var endCss = { backgroundColor: 'rgba(255, 255, 255, 0.7)' };

        if (isOpen) {
            this.isOpen = true

            this.animation(
                true,
                this.modalElement,
                400,
                startCss,
                endCss,
                null
            );
        }
        else {
            this.animation(
                isOpen,
                this.modalElement,
                400,
                startCss,
                endCss,
                () => {
                    this.isOpen = false;
                }
            );
        }
    }

    private animation(isStart, element, duration, startCss, endCss, finishedCallback) {
        var animation = this.animationBuilder.css();

        animation.setDuration(duration);

        if (isStart) {
            animation.setFromStyles(startCss).setToStyles(endCss);
        } else {
            animation.setFromStyles(endCss).setToStyles(startCss)
        }

        animation.start(element);

        if (finishedCallback) {
            setTimeout(finishedCallback, duration);
        }
    }
}

用法

因此,您需要一個相對容器才能使overlay填充其父級。 css肯定需要修改以適應一些場景,例如移動設備和非定位容器。 以下是它目前的使用方式:

HTML

<form action="/edit" method="post" #myForm="ngForm" (ngSubmit)="save ajax method that will update the isSaving and isSaved accordingly" novalidate>
    <div style="position: relative;" #overlayContainer>
        <overlay [isSaving]="isSaving" [isSaved]="isSaved" [containerElement]="overlayContainer"></overlay>
    </div>
</form>

保存form ,在containerElement顯示一個overlay 400ms並逐漸淡出並在之后隱藏,直到下一次保存嘗試。 isSavingisSaved綁定值是希望使用overlay的任何組件的責任。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM