Angular Material官方入门教程

翻译自Angular Material官方主页,原文地址

Angular Material官方入门教程,八步打造一个这样的app:

这个app属于一种Master-Detail布局,即左侧是用户列表,右侧是用户详情

上面同时还展示了在小尺寸设备上的显示效果。响应式的布局使得我们可以通过点击菜单按钮将用户列表隐藏,以及通过分享按钮显示底部的分享视图。

"如何创建app?"

有一些广泛使用的、规范化的app开发流程

  1. 规划你的布局和希望使用到的组件,最好有一套交互设计文档
  2. 使用常规的HTML和伪造的数据来确保组件能按希望的样式渲染
  3. 将UI组件整合到你的应用逻辑中,尽可能地和Angular的指令和控制器做到无缝整合。在整合前,你最好对应用逻辑进行单元测试。
  4. 添加合适的断点(响应式布局的触发点)
  5. 添加主题支持
  6. 添加对无障碍设计的支持
  7. 编写自动化测试,此步骤对于验证你的应用逻辑与Angular Material UI组件的配合非常重要。

此教程针对ES5

本教程假定你已经通过clone或npm install获取到了Angular Material

第一步 载入库文件

在HTML文件中引入库文件的连接即可:

<head> 
  <link href="../node_modules/angular-material/angular-material.css" rel="stylesheet" />
</head> 
<body> 
  <script src="../node_modules/angular/angular.js" type="text/javascript" ></script> 
  <script src="../node_modules/angular-animate/angular-animate.js" type="text/javascript" ></script> 
  <script src="../node_modules/angular-aria/angular-aria.js" type="text/javascript" ></script> 
  <script src="../node_modules/angular-material/angular-material.js" type="text/javascript" ></script> 
  <script> 
     // Include the dependency upon ngMaterial - important !!
     angular.module('starterApp', ['ngMaterial']); 
  </script>
</body>

第二步 容器布局

下面的插图展示了我们如何规划布局以及确定应用中的主要组件


注意,container#2是一个普通的div容器,并非Angular Material的组件

  • 添加<md-toolbar>,<md-sidenav>,<md-content>容器。<md-sidenav>容器用于包含用户列表,<md-content>容器用于包含选中用户的详情视图。
  • 添加 layoutflex属性来指定容器的布局方式和尺寸
  • 使用md-locked-open将侧边栏导航锁定在左侧
  • 使用md-whiteframe-z2来为侧边栏导航添加阴影
<body ng-app="starterApp" layout="column"> 
  <!-- Container #1 (see wireframe) -->
   <md-toolbar layout="row" >
     <h1>Angular Material - Starter App</h1> 
   </md-toolbar> 
   <!-- Container #2 -->
   <div flex layout="row">
     <!-- Container #3 --> 
     <md-sidenav md-is-locked-open="true" class="md-whiteframe-z2"></md-sidenav> 
     <!-- Container #4 --> 
     <md-content flex id="content"></md-content>
   </div>
</body>

这里使用简单的线框图来规划布局我们需要的组件和属性。然后使用Angular Material Layout api来对容器进行响应式布局。


第三步 常规HTML

在这一步你将使用常规的HTML元素和Angular Material UI组件来渲染和布局每个容器所需要的子元素。

  • md-sideNav容器中显示一个用户列表
    • 使用md-list,md-button,和md-icon组件并添加伪数据
  • md-content容器中显示用户的伪数据

注意:md-sidenav容器是用户列表的主要视图,md-content容器是用户的详情视图

<body ng-app="starterApp" layout="column">
    <md-sidenav md-is-locked-open="true" class="md-whiteframe-z2">
      <md-list>
        <!-- List item #1 -->
        <md-list-item>
          <md-button>
            <md-icon md-svg-src="./assets/svg/avatar-1.svg" class="avatar"></md-icon>
            Lia Luogo
          </md-button>
        </md-list-item>
        <!-- List item #2 -->
        <md-list-item>
          <md-button>
            <md-icon md-svg-src="./assets/svg/avatar-4.svg" class="avatar"></md-icon>
            Lawrence Ray
          </md-button>
        </md-list-item>
      </md-list>
    </md-sidenav>
    <md-content flex id="content">
      <!-- User details sample -->
      <md-icon md-svg-src="./assets/svg/avatar-1.svg" class="avatar"></md-icon>
      <h2>Lia Luogo</h2>
      <p> I love cheese... </p>
    </md-content>
</body>

第四步 动态化与伪数据

这一步我们将动态替换常规的HTML,并注入伪数据

  • 建立自定义的应用逻辑来载入伪数据
  • 创建HTML标记来渲染脚本和伪数据
    然后你就能整合你的应用逻辑
  • 定义一个Angular模块'users'并添加到你的代码中
  • 定义你的数据服务,数据模型和控制器
  • 使用script标签加载你的代码
  • 确定你的'starterApp' 模块同时注入了'ngMaterial' 和 'users'
<script src="./src/users/Users.js"></script>
<script src="./src/users/UsersListController.js"></script>
<script src="./src/users/UsersDataservice.js"></script>
<script type="text/javascript">
    angular.module('starterApp', ['ngMaterial', 'users']);       
</script>

然后使用angular指令(如:ng-repeat)将HTML替换为动态标记,b并使用{{}}注入数据

  • Angular将会编译并渲染动态HTML标记
  • 注册一套虚拟图标,让每个用户都关联一个虚拟ID
<!-- Wireframe Container #2 -->
<div flex layout="row">
    <!-- Wireframe Container #3 -->
    <md-sidenav md-is-locked-open="true" class="md-whiteframe-4dp">
      <md-list>
        <md-list-item ng-repeat="u in ul.users">
          <md-button ng-click="ul.selectUser(it)" ng-class="{'selected' : u === ul.selected }">
            <md-icon md-svg-icon="{{u.avatar}}" class="avatar"></md-icon>
            {{it.name}}
          </md-button>
        </md-list-item>
      </md-list>
    </md-sidenav>
    <!-- Wireframe Container #4 -->
    <md-content flex id="content">
      <md-icon md-svg-icon="{{ul.selected.avatar}}" class="avatar"></md-icon>
      <h2>{{ul.selected.name}}</h2>
      <p>{{ul.selected.content}}</p>
    </md-content> </div>
  <script type="text/javascript">
      angular .module('starterApp', ['ngMaterial', 'users']) .config(function( $mdIconProvider ){ 
        // Register the user `avatar` icons 
        $mdIconProvider .defaultIconSet("./assets/svg/avatars.svg", 128); 
});
   </script>

第五步 使用底部表

这一步,你将会在用户详情区域底部添加一个动态的mbBottomSheet组件,用来向其他用户展示该用户的联系方式。

  • 在用户详情视图的右上角创建一个'Share'按钮
  • 在底部表中创建联系用户视图和控制器
  • 使用$mdBottomSheet服务指定并加载底部表
  • 注册可能需要的图标

添加share按钮到视图中

  <md-content flex id="content">
    <md-icon md-svg-icon="{{ul.selected.avatar}}" class="avatar"></md-icon>
    <h2>{{ul.selected.name}}</h2>
    <p>{{ul.selected.content}}</p>
    <md-button class="share" md-no-ink ng-click="ul.makeContact(ul.selected)">
      <md-icon md-svg-icon="share"></md-icon>
    </md-button>
  </md-content>
  <script type="text/javascript">
    angular .module('starterApp', ['ngMaterial', 'users']) .config(function($mdIconProvider){ 
      $mdIconProvider.icon("share", "./assets/svg/share.svg", 24); });
  </script>

添加makeContact()函数到控制器中

  function share(selectedUser) { 
    $mdBottomSheet.show({ 
      controllerAs : "vm", 
      controller : [ '$mdBottomSheet', ContactSheetController], 
      templateUrl :'./src/users/view/contactSheet.html',                           
      parent:angular.element(document.getElementById('content'))
    });
    function ContactSheetController( $mdBottomSheet ) {
      this.user = selectedUser;
      this.items = [ 
        { name: 'Phone' , icon: 'phone' , icon_url: 'assets/svg/phone.svg'},
        { name: 'Twitter' , icon: 'twitter' , icon_url: 'assets/svg/twitter.svg'},
        { name: 'Google+' , icon: 'google_plus' , icon_url: 'assets/svg/google_plus.svg'},
        { name: 'Hangout' , icon: 'hangouts' , icon_url: 'assets/svg/hangouts.svg'} ]; 
      this.contactUser = function(action) { 
        // The actually contact process has not been implemented... 
        // so just hide the bottomSheet 
        $mdBottomSheet.hide(action);
      };
    }
  }

第六步 响应式布局

Angular Material Layout API 使用flexbox来让你的DOM容器和元素能流畅地适应你的浏览器视图宽度和高度的变化。它们还是用媒体查询来定义浏览器特定的宽度范围,让你的应用能适应新的视口大小,这些范围以下面的断点为定义:


但是对于使用Angular Material的开发者来说,使用媒体查询和断点显得太低级了,所以我们可以使用下面的别名来实现


在本节课中,你将会使用自适应断点来让你的应用实现响应式布局

  • 在工具栏中添加一个Menu按钮
  • 当设备宽度大于600px时,锁定用户列表处于打开状态,否则关闭
    • 使用$mdMedia来帮助实现这一效果
  • 当用户列表处于打开状态时,隐藏工具栏的menu图标
  • 为menu按钮添加click响应
    • 使用$mdSideNav 服务来切换侧边栏
    • 当用户被选中时,自动关闭侧边栏
  <body>
    <!-- Wireframe Container #1 -->
    <md-toolbar layout="row">
      <md-button class="menu" hide-gt-sm ng-click="ul.toggleList()" >
        <md-icon md-svg-icon="menu" ></md-icon>
      </md-button>
    </md-toolbar>
    <!-- Wireframe Container #2 -->
    <div flex layout="row">
      <!-- Wireframe Container #3 -->
      <md-sidenav md-is-locked-open="$mdMedia('gt-sm')" md-component-id="left" ng-click="ul.toggleList()" >
      </md-sidenav>
      <!-- Wireframe Container #4 -->
      <md-content flex id="content">
         <md-button class="share" md-no-ink ng-click="ul.share(ul.selected)"> 
        </md-button>
      </md-content>
    </div>
  </body>

添加menu图标

  <script type="text/javascript">
     angular .module('starterApp', ['ngMaterial', 'users']) .config(function($mdIconProvider){
      $mdIconProvider.icon("menu", "./assets/svg/menu.svg", 24);
    });
  </script>

使用Layout API 和out breakpoint aliases和组件服务

  • hide-gt-sm$mdMedia('gt-sm')
  • $mdSidenav$mdMedia

我们很快的创建了一个不光响应尺寸变化还适应断点值变化的应用

  function UserController( userService, $mdBottomSheet, $mdSidenav ) { 
    var self = this; 
    self.toggleList = toggleUsersList; 
    // ********************************* 
    // Internal methods 
    // ********************************* 
    /** 
      * Hide or Show the 'left' sideNav area 
      */ 
    function toggleUsersList() { 
      $mdSidenav('left').toggle(); 
    }
  }

第七步 主题及无障碍阅读设计

这里你将会使用特别的,更深的主题

  • 使用$mdThemingProvider服务来制定特别的主题,使用棕色作为主色,红色作为强调色
  <script type="text/javascript">
    angular .module('starterApp', ['ngMaterial', 'users']).config(function($mdThemingProvider, $mdIconProvider){
      $mdThemingProvider.theme('default') .primaryPalette('brown') .accentPalette('red');
    });
  </script>

总结

通过以上7步和几分钟的工作,我们迅速创建了一个美丽的、自适应的、主题鲜明的、可访问的以及容易保持的Angular Material 应用

想象一下没有Angular Material做这些会是什么样!
(原文的链接就是写的八步所以不要问我第八步去哪了)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容