AngularJS Phonecat实例讲解


Posted in Javascript onNovember 21, 2016

前言

最近关于AngularJS的资料也看了一些,其官网上有个实例Phonecat很不错,硬着头皮看了一会实在是看不下去,索性自己动手实现下,遇到问题时再从里面寻找答案也不失为一种好方法。说的再多、看的再多不如自己动手去做一遍,那就开始吧。

正文

1、布局

布局很简单,首页侧边栏是一个输入框和下拉框,右边是一个列表,实现时对首页不做大的修改。详情页做一些改变,尽量做一些简化,考虑加一个自定义指令(轮播图)。

2、架构分析

首先思考一下需要用到的服务。
由于我们要做的是一个单页应用,所以需要服务$route、$location。利用服务$resource获取资源。利用服务$filter对首页数据过滤以及排序。总结一下:

1).服务$route、$location负责路由管理及跳转。
2).服务$resource负责资源的获取。
3).服务$filter负责数据的过滤及排序。

3、首页及详情页view视图

1、首页视图

<div class="main">
  <div class="side">
    <p>
      <label>Search:</label>
      <input ng-model="filterKey" type="text" style="width:150px; ">
    </p>
    <p>
      <label>Sort by:</label>
      <select ng-model="sortKey">
        <option value="price">price</option>
        <option value="name" ng-selected="true">name</option>
      </select>
    </p>
  </div>
  <div class="content">
    <ul>
      <li ng-repeat="item in data" ng-click="$location.path('detail/'+item.id)">
        <img ng-src={{item.img}}>
        <div>
          <h2>名字:{{item.name}}</h2>
          <p>性能:{{item.title}}</p>
          <p>价格:{{item.price | currency}}</p>         
        </div>
      </li>
    </ul>
  </div>
</div>

2、详情页视图

<slide></slide>是一个自定义指令,实现轮播图的功能

<div class="detail">
  <slide links='links' w='200' h='200'></slide>
  <div class="text">
    <h2>设备:{{data.name}}</h2>
    <p>性能:{{data.desc}}</p>
  </div>
</div>

4、逻辑分析

1、首先说明下外部资源infor.json的信息。是一个数组,数组每一项为一个json对象,含有以下字段:

{
    "id" : 1,
    "name" : "aaa",
    "title" : "bbb",
    "desc" : "ccc",
    "img" : "img/a.jpg",
    "price" : 100,
    "showList" : "[{"url":"img/b.jpg"},{"url":"img/c.jpg"}]"
}

2、路由管理($route)

m1.config(['$routeProvider',function($routeProvider){

  $routeProvider
    .when('/index',{
      templateUrl : 'template/index.html',
      controller : 'index'
    })
    .when('/detail/:str',{
      templateUrl : 'template/detail.html',
      controller : 'detail'  
    })
    .otherwise({
      redirectTo : '/index'
    });

}]);

当形如http://localhost/phonecat/phone.html#/index加载index模板

当形如http://localhost/phonecat/phone.html#/detail/0加载detail模板

默认为http://localhost/phonecat/phone.html#/index

3、首页(index)逻辑分析

首页资源加载:

var arr = [];
var objRe = $resource('infor.json');  
$scope.data = arr = objRe.query(); //获得data数据后首页即可进行渲染

首页数据的过滤及排序:

$scope.$watch('filterKey',function(){ //监听输入框的数据变化,完成数据的筛选
    if($scope.filterKey){
      $scope.data = $filter('filter')(arr,$scope.filterKey);
    }else{
      $scope.data = arr; 
    }  
  })

  $scope.$watch('sortKey',function(){  //监听select下拉框的数据变化,完成数据的排序
    if($scope.sortKey){
      $scope.data = $filter('orderBy')($scope.data,$scope.sortKey); 
    }else{
      $scope.data = arr;
    }
  })


//这里有个需要注意的地方,我们用一个数组arr作为媒介,避免bug

点击列表进行详情页的跳转:

$scope.$location = $location; //将$location挂载到$scope下,模板中便可使用$location提供的方法

模板如下:

<li ng-repeat="item in data" ng-click="$location.path('detail/'+item.id)">  --点击的时候将列表跳转到详情页

4、详情页(detail)逻辑分析

m1.controller('detail',['$scope','$resource','$location',function($scope,$resource,$location){
  var id = parseInt($location.path().substring(8));  //获取索引
  $resource('infor.json').query(function(data){
    $scope.data = data[id];
    $scope.links = eval($scope.data.showList);  //自定义指令需要用到此数据
  });

}]);

//注意:$resource.query()为异步操作。数据相关的逻辑需要在回调中完成,否则可能会出现数据undefined的情况。

5、自定义指定slide的编写

AngularJS的自定义指定功能十分强大,为实现组件化开发提供了一种思路。下面简单地实现一个轮播组件。

用法示例: <slide links='links' w='200' h='200'></slide>

模板(slide.html)如下:

<div class="slide">
 <ul>
   <li ng-repeat="item in links">
     <img ng-src={{item.url}}>
   </li>
 </ul>
</div>
m1.directive('slide',function(){
  return {
    restrict : 'E',
    templateUrl : 'template/slide.html',
    replace : true,
    scope : {
      links : '=',
      w : '@',
      h : '@'
    },
    link : function(scope,element,attris){
      setTimeout(function(){
        var w = scope.links.length * scope.w;
        var h = scope.h;
        var iNow = 0;

        $(element).css({'width':scope.w,'height':h,'position':'relative','overflow':'hidden'})
        $(element).find('ul').css({'width':w,'height':h,'position':'absolute'});
        setTimeout(function(){
          $(element).find('li').css({'width':scope.w,'height':h,'float':'left'});
          $(element).find('img').css({'width':scope.w,'height':h});       
        },0);

        setInterval(function(){
          iNow++;
          $(element).find('ul').animate({'left':-iNow*scope.w},function(){
            if(iNow==scope.links.length-1){
              $(element).find('ul').css('left',0);
              iNow = 0;  
            }  
          });
        },1000)       
      },50)

    }
  }  
})

结语

AngularJS给我们提供了很多好用的功能,比如路由的管理、数据的过滤的等。更强大的功能还需要进一步的探索,此文仅作为一个好的开端。

Javascript 相关文章推荐
Javascript对象中关于setTimeout和setInterval的this介绍
Jul 21 Javascript
在JavaScript里嵌入大量字符串常量的实现方法
Jul 07 Javascript
多种方法实现JS动态添加事件
Nov 01 Javascript
基于JavaScript实现一定时间后去执行一个函数
Dec 14 Javascript
jQuery插件EasyUI获取当前Tab中iframe窗体对象的方法
Aug 05 Javascript
node中Express 动态设置端口的方法
Aug 04 Javascript
React实践之Tree组件的使用方法
Sep 30 Javascript
AngularJS 中的数据源的循环输出
Oct 12 Javascript
zTree树形菜单交互选项卡效果的实现方法
Dec 25 Javascript
Angular2 父子组件通信方式的示例
Jan 29 Javascript
使用Vue制作图片轮播组件思路详解
Mar 21 Javascript
js 压缩图片的示例(只缩小体积,不更改图片尺寸)
Oct 21 Javascript
浅谈React 属性和状态的一些总结
Nov 21 #Javascript
JavaScript中关于for循环删除数组元素内容时出现的问题
Nov 21 #Javascript
jQuery用FormData实现文件上传的方法
Nov 21 #Javascript
遍历js中对象的属性和值的实例
Nov 21 #Javascript
JavaScript数据结构链表知识详解
Nov 21 #Javascript
jQuery简单自定义图片轮播插件及用法示例
Nov 21 #Javascript
Node.js测试中的Mock文件系统详解
Nov 21 #Javascript
You might like
DSP接收机前端设想
2021/03/02 无线电
PHP的FTP学习(二)
2006/10/09 PHP
PHP 字符串 小常识
2009/06/05 PHP
php中通过正则表达式下载内容中的远程图片的函数代码
2012/01/10 PHP
php中http_build_query 的一个问题
2012/03/25 PHP
ThinkPHP查询中的魔术方法简述
2014/06/25 PHP
yii2.0实现验证用户名与邮箱功能
2015/12/22 PHP
CentOS 7.2 下编译安装PHP7.0.10+MySQL5.7.14+Nginx1.10.1的方法详解(mini版本)
2016/09/01 PHP
Laravel如何实现适合Api的异常处理响应格式
2020/06/14 PHP
ie 调试javascript的工具
2009/04/29 Javascript
Javascript UrlDecode函数代码
2010/01/09 Javascript
document.getElementById方法在Firefox与IE中的区别
2010/05/18 Javascript
jQuery选择没有colspan属性的td的代码
2010/07/06 Javascript
文本框(input)获取焦点(onfocus)时样式改变的示例代码
2014/01/10 Javascript
JavaScript实现的使用键盘控制人物走动实例
2014/08/27 Javascript
jQuery实现简单的DIV拖动效果
2016/02/19 Javascript
Three.js学习之网格
2016/08/10 Javascript
Angularjs通过指令监听ng-repeat渲染完成后执行脚本的方法
2016/12/31 Javascript
vue 中自定义指令改变data中的值
2017/06/02 Javascript
BootStrap入门学习第一篇
2017/08/28 Javascript
详解如何使用webpack在vue项目中写jsx语法
2017/11/08 Javascript
原生js封装的ajax方法示例
2018/08/02 Javascript
微信小程序实现日期格式化和倒计时
2020/11/01 Javascript
Servlet返回的数据js解析2种方法
2019/12/12 Javascript
Vue中使用wangeditor富文本编辑的问题
2021/02/07 Vue.js
[04:28]2014DOTA2国际邀请赛 采访小兔子LGD挺进钥匙体育馆
2014/07/14 DOTA
Django框架封装外部函数示例
2019/05/28 Python
如何使用python操作vmware
2019/07/27 Python
使用Python实现正态分布、正态分布采样
2019/11/20 Python
Python实现哲学家就餐问题实例代码
2020/11/09 Python
内部类的定义、种类以及优点
2013/10/16 面试题
建筑专业毕业生推荐信
2013/11/21 职场文书
给实习单位的感谢信
2014/02/01 职场文书
党员公开承诺书
2014/03/25 职场文书
事业单位财务人员岗位职责
2015/04/14 职场文书
vue中 this.$set的使用详解
2021/11/17 Vue.js