简体   繁体   English

如何在角度2中实现阻止ui的行为

[英]How to achieve block ui kind of behaviour in angular 2

How is it possible to achieve block ui( http://malsup.com/jquery/block/#demos ) kind of blocking user interaction in angular 2 ? 如何在角度2中实现块ui( http://malsup.com/jquery/block/#demos )阻止用户交互? Could someone please help. 请有人帮忙。

spinner.ts spinner.ts

import {Component} from 'angular2/core';

@Component({
    selector: 'spinner',
    styleUrls: ['spinner.css'],
    //I'm using in modal-backdrop classes from bootstrap
    template:
    `<div class="in modal-backdrop spinner-overlay"></div>
     <div class="spinner-message-container" aria-live="assertive" aria-atomic="true">
        <div class="spinner-message" [ngClass]="spinnerMessageClass">{{ state.message }}</div>
    </div>`
})
export class SpinnerComponent {
    state = {
        message: 'Please wait...'
    };
}

spinner.css spinner.css

.spinner-overlay {
  background-color: white;
  cursor: wait;
}

.spinner-message-container {
  position: absolute;
  top: 35%;
  left: 0;
  right: 0;
  height: 0;
  text-align: center;
  z-index: 10001;
  cursor: wait;
}

.spinner-message {
  display: inline-block;
  text-align: left;
  background-color: #333;
  color: #f5f5f5;
  padding: 20px;
  border-radius: 4px;
  font-size: 20px;
  font-weight: bold;
  filter: alpha(opacity=100);
}

spinner.service.ts spinner.service.ts

import {Injectable, DynamicComponentLoader, ApplicationRef, ElementRef, ComponentRef} from 'angular2/core';

import {SpinnerComponent} from './spinner.component';

@Injectable()
export class SpinnerService {
    spinnerComp: ComponentRef;
    constructor(private componentLoader: DynamicComponentLoader, private appRef: ApplicationRef) { }

    public start() {
        let elementRef: ElementRef = this.appRef['_rootComponents'][0].location;

        return this.startInside(elementRef, null);
    }

    public startInside(elementRef: ElementRef, anchorName: string) {

        let spinnerRef = (!anchorName) ?
                            this.componentLoader.loadNextToLocation(SpinnerComponent, elementRef) :
                            this.componentLoader.loadIntoLocation(SpinnerComponent, elementRef, anchorName);

        spinnerRef.then((compRef:ComponentRef) => {
            this.spinnerComp = compRef;
        });
    }

    public stop() {
        if (this.spinnerComp) {
            this.spinnerComp.dispose();
        }
    }
}

Inject spinner service to your component. 将微调器服务注入组件。 call start and stop to display and hide. 调用开始和停止显示和隐藏。

update : demo plnkr link: http://plnkr.co/edit/Y2ocRpbi2ORjbULrguDg 更新 :演示plnkr链接: http ://plnkr.co/edit/Y2ocRpbi2ORjbULrguDg

disclaimer: I have used one existing angular2 library as reference to create above code in my project. 免责声明:我使用一个现有的angular2库作为参考,在我的项目中创建上面的代码。 I'm searching for that library and will update the same here when I find it. 我正在搜索该库,并在找到它时将在此处更新。

Angular 2 blockui with spinner (can be customized as per your needs) 带旋转器的Angular 2 blockui(可根据您的需要定制)

Please find below code which works perfectly with angular 2 请找到下面与角度2完美配合的代码

spinner.component.ts spinner.component.ts

import {Component, Input, OnDestroy} from '@angular/core';

@Component({
    selector: 'my-spinner',
    //templateUrl: 'app/components/spinner/spinner.html'
    template: `
    <div [hidden]="!isDelayedRunning" class="spinnercontainer">
        <div class="spinner">  
            <div class="double-bounce1"></div>
            <div class="double-bounce2"></div>
        </div>
    </div>  
    `,
    styleUrls:['app/spinner.component.css']
})
export class SpinnerComponent implements OnDestroy {  
    private currentTimeout: any;
    private isDelayedRunning: boolean = false;

    @Input()
    public delay: number = 300;

    @Input()
    public set isRunning(value: boolean) {
        if (!value) {
            this.cancelTimeout();
            this.isDelayedRunning = false;
        }

        if (this.currentTimeout) {
            return;
        }

        this.currentTimeout = setTimeout(() => {
            this.isDelayedRunning = value;
            this.cancelTimeout();
        }, this.delay);
    }

    private cancelTimeout(): void {
        clearTimeout(this.currentTimeout);
        this.currentTimeout = undefined;
    }

    ngOnDestroy(): any {
        this.cancelTimeout();
    }
}

spinner.component.css spinner.component.css

.spinnercontainer{
    background-color: transparant;
    height: 100vh;
    width: 100%;
    z-index: 20000;
    position: fixed;
    top: 0;
    left: 0;
    background-color: #000;
    opacity: 0.5;
    transition: all 0.5s ease;
    display:block;
    z-index: 20001;
}
.spinner {
  width: 40px;
  height: 40px;
  position: relative;
  margin: 100px auto;
}

.double-bounce1, .double-bounce2 {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: #333;
  opacity: 0.6;
  position: absolute;
  top: 0;
  left: 0;

  -webkit-animation: sk-bounce 2.0s infinite ease-in-out;
  animation: sk-bounce 2.0s infinite ease-in-out;
}

.double-bounce2 {
  -webkit-animation-delay: -1.0s;
  animation-delay: -1.0s;
}

@-webkit-keyframes sk-bounce {
  0%, 100% { -webkit-transform: scale(0.0) }
  50% { -webkit-transform: scale(1.0) }
}

@keyframes sk-bounce {
  0%, 100% {
    transform: scale(0.0);
    -webkit-transform: scale(0.0);
  } 50% {
      transform: scale(1.0);
      -webkit-transform: scale(1.0);
    }
}

How to use: Use above component in other component(which uses async task) as shown below 使用方法:在其他组件(使用异步任务)中使用上述组件,如下所示

sample-view.component.ts 样品view.component.ts

import {Component} from '@angular/core';

import {SpinnerComponent} from './spinner.component';  
import {ApiService} from './apiService';

@Component({
    selector: 'my-sample-view',
    directives: [SpinnerComponent],
    template: '<my-spinner [isRunning]="isRequesting"></my-spinner>',
})
export class SampleViewComponent {  
    public isRequesting: boolean;
    public items: Array<any>;

    constructor(private apiService: ApiService) {
        this.refresh();
    }

    public refresh(): void {
        this.isRequesting = true;
        this.apiService.sampleHttpGetRequest()
            .subscribe(
                result => this.items = result, 
                () => this.stopRefreshing(),
                () => this.stopRefreshing());
    }

    private stopRefreshing() {
        this.isRequesting = false;
    }
}

Thanks to https://manuel-rauber.com/2016/01/05/angular-2-spinner-component/ 感谢https://manuel-rauber.com/2016/01/05/angular-2-spinner-component/

Modifying the previous answer, and updating for Angular 2 RC1. 修改上一个答案,并更新Angular 2 RC1。

blockUi.ts (note you need some soft of spinner.gif) blockUi.ts(注意你需要一些软的spinner.gif)

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

@Component({
    selector: 'blockUi',
    template:
    `<div class="in modal-backdrop block-ui-overlay"></div>
     <div class="block-ui-message-container" aria-live="assertive" aria-atomic="true">
        <div class="block-ui-message">
            <table>
                <tr><td class='center space'>{{ message }}</td></tr>
                <tr><td class='center'><img src="/styles/img/spinner.gif" /></td></tr>
            </table>
        </div>        
    </div>`,
    styles: [`
.block-ui-overlay {
  background-color: white;
  cursor: wait;
}
.block-ui-message-container {
  position: absolute;
  top: 35%;
  left: 0;
  right: 0;
  height: 0;
  text-align: center;
  z-index: 10001;
  cursor: wait;
}
.block-ui-message {
  display: inline-block;
  text-align: left;
  background-color: #333;
  color: #f5f5f5;
  padding: 20px;
  border-radius: 4px;
  font-size: 20px;
  font-weight: bold;
  filter: alpha(opacity=100);
}
.center {
  text-align: center;
}
.space {
  padding-bottom: 10px;
}`]
})
export class BlockUi {
    message: string = 'Please wait...';
}

blockUiService.ts blockUiService.ts

import { Injectable, Inject, DynamicComponentLoader, ApplicationRef, ViewContainerRef, ComponentRef } from '@angular/core';
import { BlockUi } from '../components/blockUi';    

@Injectable()
export class BlockUiService {

    blockUi: ComponentRef<BlockUi>;

    constructor(
        @Inject(DynamicComponentLoader) private dynamicComponentLoader: DynamicComponentLoader,
        @Inject(ApplicationRef) private applicationRef: ApplicationRef) { }

    start(message?: string) {

        const viewContainerRef: ViewContainerRef = this.applicationRef['_rootComponents'][0]._hostElement.component.viewContainerRef;

        return this.startInside(viewContainerRef, message);
    }

    startInside(viewContainerRef: ViewContainerRef, message?: string) {

        const blockUiRef = this.dynamicComponentLoader.loadNextToLocation(BlockUi, viewContainerRef);

        blockUiRef.then((compRef: ComponentRef<BlockUi>) => {
            this.blockUi = compRef;
            if (message !== undefined && message !== null && message.length > 0 ) {
                const blockUiInstance: BlockUi = compRef.instance;
                blockUiInstance.message = message;
            }
        });
    }

    stop() {
        if (this.blockUi) {
            this.blockUi.destroy();
        }
    }
}

Usage 用法

constructor(
    @Inject(BlockUiService) private blockUiService: BlockUiService
) {}

this.blockUiService.start("Saving Data...");

...

this.blockUiService.stop();

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM