Brian F Love
Learn from a Google Developer Expert focused on Angular, Web Technologies, and Node.js from Portland, OR.
Ad ·ultimatecourses.com.
用终极课程学习角度正确的方式

Responsive Angular

Learn how to easily create responsive applications using Angular and Flex Layout.

目标

Some goals for my app:

  1. 采用Flex Layout角分量布局发动机。
  2. Create a responsivemat-grid-listusing Angular Material.
  3. 不写任何Sass或CSS.

Here you can see that I have anmat-grid-listwith fourmat-grid-tile儿童,指定固定数量的列至2:

fxlayout行示例

As I indicated I want my design to be responsive in that tiles "2" and "4" will flow down when we hit the extra-small break point (most likely for a mobile device). The solution is to set thecols输入到我组件中的变量的输入绑定,该组件由浏览器的宽度决定。但是,我该怎么做?这是我们要解决的问题。

Flex Layout

我们的解决方案:角度柔性布局。什么是Flex布局?根据他们关于GitHub的项目细节:

Angular Flex Layout provides a sophisticated layout API using Flexbox CSS + mediaQuery.

In my opinion:

Angular + Flex Layout = Web Dev Dream

Flex Layout enables us to use flex-based layouts for modern browsers without having to master Flexbox. Sounds too good to be true, right?

Getting Started

The basic directives that you will use most often arefxLayoutfxLayoutAlign

ThefxLayout指令指定了我们的元素的行为与块元素一样,内容使用Flexbox模型,以及子元素的Flex方向。两个可能的值fxLayoutdirective is either要么column

ThefxLayoutAlign指令指定主轴和横轴上的子元素的对齐。

您可以了解更多有关这些指令的细节,以及附加指令API文档page.

弯曲方向: row

首先,让我们来看看创建一个简单的元素。为此,我们将使用fxLayoutdirective with thevalue. I am also going to use thefxLayoutAligndirective to specify the alignment of the child elements. In this example I am going to set the main-axis tocenter和the cross-axis tocenter此外,我在父元素上设置了固定的高度,以便我们可以看到对齐方式是如何工作的。

<divfxLayout=""fxLayoutAlign="center center"class="行示例"><div>1div><div>2div><div>3div>div>

Here is how this is displayed in the browser:

fxlayout行示例

很酷,呃?

弯曲方向:列

Ok, now that we saw the basics of usingfxLayout让我们设置弯曲方向tocolumn:

<divfxLayout="column"fxLayoutAlign="中心伸展"class="column-example"><div>1div><div>2div><div>3div>div>

Here is how this is displayed in the browser:

fxlayout行示例

Not much has changed. First, I updated thefxLayouttocolumn。其次,我改变了fxLayoutAligncross-axis alignment tostretch

Check outthis simple app to explore thefxLayoutAlign价值使用Flex布局设置子对齐的可用值更加舒适。

Flex Layout Plunker

查看以下亵渎,以便在实践中看到上面的两个示例:

Breakpoints

The Angular Flex Layout uses media queries to defined the following breakpoints:

  • xs - max-width: 599 px;
  • gt-xs - min-width: 600px;
  • sm - min-width: 600px; max-width: 959px;
  • gt-sm - min-width: 960px;
  • MD - min宽:960px;最大宽度:1279px;
  • GT-MD - MIN宽度:1280;
  • lg - min-width: 1280px; max-width: 1919px;
  • gt-lg - min-宽度:1920px;
  • xl - min-width: 1920px; max-width: 5000px;

Note that the list above uses the aliases by which you can reference the breakpoints. We will be using these aliases next when we are using theObservableMedia服务以编程方式确定特定断点是否处于活动状态。

We can also combine the use of the above aliases with the static flex layout API, including thefxLayoutfxLayoutAligndirectives. For example, if we want to have a column layout on mobile devices (xs) but use rows otherwise we can use the responsive API and breakpoints:

<divfxLayout=""fxLayout.xs="column"fxLayoutAlign="center center"fxLayoutAlign.xs="中心伸展"class="行示例"><div>1div><div>2div><div>3div>div>

Note the appended breakpoint.x.that will be trigger the column layout when the device width is less than 600px.

Toggle visibility

You can also use theFXHIDE.fxShow指令与响应API结合切换显示基于浏览器宽度的元素的属性。注意,与...不同* ngif.在核心角库中指令这些不会添加/删除元素和来自DOM的所有子项。就像我说的那样,它只是切换了CSS显示property.

Here is a quick demo:

<divfxShow="真正"fxhide.xs.="真正"><div>1div><div>2div><div>3div>div>

In the example above I toggle the显示父母上的CSS属性divelement so that the element is not displayed on devices where the browser width is less than 600px. As with all of the static/declarative APIs you can combine multiple responsive API declarations as needed.

TheObservableMediaservice

好的,让我们回到我们创建响应角材料的目标mat-grid-listusing Flex Layout. To solve this problem we need to introduce theObservableMediaservice.

究竟是什么ObservableMediaservice? According to thewiki page:

The injectable ObservableMedia service will provide mediaQuery activations notifications for all registered BreakPoints.

Let's dive in. First, we need to install Flex Layout:

$npminstall@angular/flex-layout --save

Next, modifyappmodule.to import theFlexLayoutModule:

import{ngmodule.}'@angular/core';import{浏览器}'@ Angular / platform-b​​rowser';import{FlexLayoutModule}'@angular/flex-layout';// 零件import{应用程序}'./app.component';@ngmodule.({进口:[浏览器,FlexLayoutModule],宣言:[应用程序],引导:[应用程序],})exportclassappmodule.{}

Note two things:

  • 首先,我使用importstatement to import theFlexLayoutModule
  • 其次,我更新了进口array in thengmodule.decorator to include theFlexLayoutModule

现在我们有了FlexLayoutModule进口,我们需要导入ObservableMedia服务进入我们的组件:

import{ObservableMedia}'@angular/flex-layout';

Then inject the service in the构造函数()function for the component:

constructor(privateobservableMedia:ObservableMedia){}

接下来,让我们在我们的组件中创建一个公开的变量,我们将绑定到colsinput to themat-grid-listdirective:

/ ** * Mat-G​​rid-list指令中的COLUM数量。* /上市cols:number=2;

And now bind thecolsinput to the variable value:

<mat-grid-list[cols]="cols"gutterSize="16px"><mat-grid-tile>1mat-grid-tile><mat-grid-tile>2mat-grid-tile><mat-grid-tile>3mat-grid-tile><mat-grid-tile>5mat-grid-tile>mat-grid-list>

好的,要测试这让我们将COL的值设置为不同的数字ngOnInit()生命周期方法:

ngOnInit(){// set colsthiscols=1;}

Your grid should now be displaying with a single column. Cool, our binding is working. Now, let's put theObservableMediaservice to work.

首先,让我们改变我们的cols变量是一个Observableof anumber。To do this, we need to first import theObservableclass from therxjspackage.RxJSis a reactive extensions library for JavaScript.

If you have not installed rxjs, do that via:

$npminstallrxjs --save.

Then, importObservableas well as some additional operators:

import{Observable}'rxjs /可观察';import'rxjs / add / operator / map';import'rxjs/add/operator/takeWhile';import'rxjs/add/operator/startWith';

然后,改变我们的colsvariable type declaration to:

/ ** * Mat-G​​rid-list指令中的COLUM数量。* /上市cols:Observable<number>;

To subscribe to the observable in our template we will take advantage Angular's异步。So, let's update thecolsinput binding on themat-grid-listto:

<mat-grid-list[cols]="cols |异步"gutterSize="16px"><mat-grid-tile>1mat-grid-tile><mat-grid-tile>2mat-grid-tile><mat-grid-tile>3mat-grid-tile><mat-grid-tile>5mat-grid-tile>mat-grid-list>

Then, in thengOnInit()lifecycle method we will observe for break point activation changes and update the value ofcols适当的。

ngOnInit(){const=Map([["xs",1],[“sm”,2],["md",2],["lg",3],["xl",3]]);letstart:number;Foreach.((cols,mqalias.)=>{if(thisobservableMedia活跃(mqalias.)){start=cols;}});thiscols=thisobservableMediaasObservable()地图(更改=>{安慰日志(更改);安慰日志(得到(更改mqalias.));返回得到(更改mqalias.);})从...开始(start);}

In this example I am setting the columns to:

  • 1 column - for xs
  • 2列 - 用于SM和MD断点
  • 3 column - for both lg and xl break points

Let me quickly explain what is going on:

  • 首先,我定义一个新的地图that maps the media query alias strings to the number of columns I want for my grid.
  • 然后,我正在计算启动值colsnumber. I iterate over each item in the map, checking if the breakpoint alias is currently active using the活跃()method on theObservableMediaclass.
  • Then, using theasObservable()method I set the value ofcolsto an observable, invoking the地图()operator to return the corresponding number value.

在行动中看到它:

结论

Responsive is critical, and with Angular and Flex Layout, it's easily accomplished. Plus, theObservableMediaservice enables us to work with media query break points in our Angular components.

Brian F Love

嗨,我是布莱恩。我对类型名称,Angular和node.js感兴趣我嫁给了我最好的朋友邦妮,我住在波特兰和我滑雪(很多)。