在Angular2中如何做响应组件

前端之家收集整理的这篇文章主要介绍了在Angular2中如何做响应组件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在闯入Angular2.我的目标是创建一个响应应用程序,加载不同的组件以响应不同的设备宽度的媒体查询.我的工作示例有一个MatchMediaService:
import { Injectable } from '@angular/core';

@Injectable()
export class MatchMediaService 
{
    constructor()
    {

    }

    rules =
    {
        print: "print",screen: "screen",phone: '(max-width: 767px)',tablet: '(min-width: 768px) and (max-width: 1024px)',desktop: '(min-width: 1025px)',portrait: '(orientation: portrait)',landscape: '(orientation: landscape)',retina: '(-webkit-min-device-pixel-ratio: 2),(min-resolution: 192dpi)'
    };

    Check = function (mq)
    {
        if (!mq)
        {
            return;
        }

        return window.matchMedia(mq).matches;
    };

/**********************************************
    METHODS FOR CHECKING TYPE   
 **********************************************/
    IsPhone()
    {
        return window.matchMedia(this.rules.phone).matches;
    };

    IsTablet = function ()
    {
        return window.matchMedia(this.rules.tablet).matches;
    };

    IsDesktop = function ()
    {
        return window.matchMedia(this.rules.desktop).matches;
    };

    IsPortrait = function ()
    {
        return window.matchMedia(this.rules.portrait).matches;
    };

    IsLandscape = function ()
    {
        return window.matchMedia(this.rules.landscape).matches;
    };

    IsRetina = function ()
    {
        return window.matchMedia(this.rules.retina).matches;
    };


/**********************************************
    EVENT LISTENERS BY TYPE
 **********************************************/    
    OnPhone(callBack)
    {
        if (typeof callBack === 'function')
        {
            var mql: MediaQueryList = window.matchMedia(this.rules.phone);

            mql.addListener((mql: MediaQueryList) =>
            {
                if (mql.matches)
                {
                    callBack(mql);
                }
            });
        }
    };

    OnTablet(callBack)
    {
        if (typeof callBack === 'function')
        {
            var mql: MediaQueryList = window.matchMedia(this.rules.tablet);

            mql.addListener((mql: MediaQueryList) =>
            {
                if (mql.matches)
                {
                    callBack(mql);
                }
            });
        }
    };

    OnDesktop(callBack)
    {
        if (typeof callBack === 'function')
        {
            var mql: MediaQueryList = window.matchMedia(this.rules.desktop);

            mql.addListener((mql: MediaQueryList) =>
            {
                if (mql.matches)
                {
                    callBack(mql);
                }
            });
        }
    };  

    OnPortrait(callBack)
    {
        if (typeof callBack === 'function')
        {
            var mql: MediaQueryList = window.matchMedia(this.rules.portrait);

            mql.addListener((mql: MediaQueryList) =>
            {
                if (mql.matches)
                {
                    callBack(mql);
                }
            });
        }
    };  

    OnLandscape(callBack)
    {
        if (typeof callBack === 'function')
        {
            var mql: MediaQueryList = window.matchMedia(this.rules.landscape);

            mql.addListener((mql: MediaQueryList) =>
            {
                if (mql.matches)
                {
                    callBack(mql);
                }
            });
        }
    };
}

然后在“父”组件(HomeComponent)中,我使用MatchMediaService来确定要根据MatchMediaService返回的哪个子组件(HomeMobileComponent或HomeDesktopComponent)以及浏览器通过不同维度调整大小时触发的侦听器事件:

import { Component,OnInit,NgZone } from '@angular/core';
import { MatchMediaService } from '../shared/services/match-media.service';
import { HomeMobileComponent } from './home-mobile.component';
import { HomeDesktopComponent } from './home-desktop.component';

@Component({
    moduleId: module.id,selector: 'home.component',templateUrl: 'home.component.html',providers: [ MatchMediaService ],directives: [ HomeMobileComponent,HomeDesktopComponent ]
})
export class HomeComponent implements OnInit 
{
    IsMobile: Boolean = false;
    IsDesktop: Boolean = false;

    constructor(
        private matchMediaService: MatchMediaService,private zone: NgZone        
    )
    {
        //GET INITIAL VALUE BASED ON DEVICE WIDTHS AT TIME THE APP RENDERS
        this.IsMobile = (this.matchMediaService.IsPhone() || this.matchMediaService.IsTablet());
        this.IsDesktop = (this.matchMediaService.IsDesktop());

        var that = this;


        /*---------------------------------------------------
        TAP INTO LISTENERS FOR WHEN DEVICE WIDTH CHANGES
        ---------------------------------------------------*/

        this.matchMediaService.OnPhone(
            function (mediaQueryList: MediaQueryList)
            {
                that.ShowMobile();
            }
        );

        this.matchMediaService.OnTablet(
            function (mediaQueryList: MediaQueryList)
            {
                that.ShowMobile();
            }
        );

        this.matchMediaService.OnDesktop(
            function (mediaQueryList: MediaQueryList)
            {
                that.ShowDesktop();
            }
        );
    }

    ngOnInit()
    {

    }

    ShowMobile()
    {
        this.zone.run(() =>
        { // Change the property within the zone,CD will run after
            this.IsMobile = true;
            this.IsDesktop = false;
        });
    }

    ShowDesktop()
    {
        this.zone.run(() =>
        { // Change the property within the zone,CD will run after
            this.IsMobile = false;
            this.IsDesktop = true;
        });
    }   
}
<home-mobile *ngIf="(IsMobile)"></home-mobile>
<home-desktop *ngIf="(IsDesktop)"></home-desktop>

这种方法有效.我可以加载相应的组件来响应设备.它使我能够自定义组件(内容,样式,功能等)到设备,从而实现最佳的用户体验.这也使我有能力针对移动,平板电脑和桌面的不同组件(尽管我只关注移动和桌面).

有没有更好的方法来做到这一点?缺点是我迫使每个组件由父组件组成,以通过MatchMediaService来确定要加载的子组件.这是否可以扩展到一个完整的生产级应用程序?我对一个更好的方法的反馈非常感兴趣,或者这种方法对于一个完整的生产应用程序是可以接受和可扩展的.感谢您的反馈.

您可以创建自定义的媒体感知* ngIf或* ngSwitch结构指令,使其不太重复.

https://angular.io/docs/ts/latest/guide/structural-directives.html

猜你在找的Angularjs相关文章