发表于: 2017-06-15 21:27:39
1 1022
今天完成的事情:
运动商店如何做成的过了一遍。
明天计划的事情:
继续看下运动商店怎么实现的代码
遇到的问题:
暂无
收获:
写一个运动商店应用程序
他必须的文件夹如下
然后加入必须的三个,angular.js,bootstrap.css,bootstrap-theme.css
构件基本大纲
该文件包括定义基本布局的HTML元素,使用Bootstrap设计表格结构,还有两个是angularJS特有的格式。第一个就是angular.module方法。模块是在一个AngularJS应用程序中的顶级构建块,调用该方法创建了叫做sportsStore的新模块。这是马上创建模块的唯一做法。
第二各方面是在html元素上应用了ng-app指令,ng-app指令使定义在sportsStore模块中的功能在HTML中也可用。
创建控制器
注意该文件中的第一段是调用angular.module方法。这和前面调用的方法一样,定义运动商店应用程序的主模块。不同的是当我定义模块时,我提供了额外的参数,
angular.module("sportsStore", []);
第二个参数是数组,目前是空的,他列出模块依赖于运动商店的哪些模块,并让angularJS找到并提供这些模块所提供的功能。相比之下,在sportsStroe.js中文件调用angular.module方法没有第二个参数
angular.module("sportsStore")
第二个参数的缺失会告诉AngularJS,我想找到已经定义的模块。在这种情况下,如果指定的模块不存在,AAngularJS会报告错误,所以你需要确保模块已经被创建。
两种angular.module方法的使用都返回Module对象,它可用于应用程序的定义。
顶级控制器在运动商店应用的主要角色是,定义将被应用于应用程序要显示的不同视图。正如你将看到的AngularJS可以将多个控制器放在一个层级中。而被放的控制器用这种方式可以从他们上层的控制器那集成数据和逻辑,而且通过在顶级控制器中定义数据,我可以让其更易于使用我稍后将定义的控制器。
显示产品信息
该清单中有三种不同的改变值值得注意。第一个是添加了script元素从controllers文件夹引入sportsStore.js文件。它包含sportsStoreCtrl控制器。因为我在app.html文件中定义了sportsStore模块,还在sportsStore.js文件中找到并使用了它,所以我需要确保内联script元素出现前就引入该文件。
另一个改动使用ng-controller指令为其视图使用控制器,如下:
<body ng-controller="sportsStoreCtrl">
我会在整个应用程序中使用sportsStoreCtrl控制器,所以我在body元素上应用了它,一次让他支持的视图是完整的内容元素集合。
生成内容元素
AngularJS所提供的最有用的指令之一是ng-repeat,他为每个数据数组中的对象生成元素。ng-repeat指令作为属性的值而被应用,他为指定数组中的每个数据对象创建本地变量,像这样:
<div ng-repeat="item in data.products">
我使用的值告诉ng-repeat指令枚举控制器为视图应用在作用域上的data.products数组中的对象,并将每个对象赋给叫做item的变量,然后我就可以在数据绑定表达式中引用当前的对象,他和{{和}}符号一起表示,如下
<div ng-repeat="item in data.products">
<h3>
<strong>{{item.name}}</strong>
<span class="pull-right label label-primary">
{{item.price | currency}}
</span>
</h3>
<span>{{item.description}}</span>
</div>
ng-repeat指令为每个数据对象重复其所应用的元素。数据对象被赋给变量item,以让我能按需插入name、price和decription属性的值。
属性name和description的值是原样插入HTML元素的,但我对price属性做的稍有不同:我是用了过滤器。一个在视图中格式化和排序数值以显示的过滤器。AngularJS附带了一些内置过滤器,包括curreney过滤器,它将数字值格式化为金额。过滤器通过"|"符号使用,接着是过滤器的名称,比如那个表达式item.price | currency告诉AngularJS将item对象的price属性的值传入currency过滤器。
显示分类列表
下一步是显示分类列表,让用户可以滤出显示的一组产品。实现该功能需要伴随用于的导航而生成元素,单击导航选择产品分类,然后最终更新详情,让被选分类中产品显示。
创建分类列表
我想以产品数据对象动态生成分类元素,而不是写死HTML元素固定分类的设置。动态方法设置起来很复杂,但它会让运动商店应用程序自动地在产品目录中反映变化。这意味着我必须得根据产品数据对象的数组来生成唯一分类名的列表。这个是AngularJS没包括的功能,但创建并应用自定义过滤器很容易实现。如下我在filters目录中创建了文件customeFilters.js
自定义过滤器使用module对象定义的filter方法创建,通过angular.module方法获取和创建。
所有过滤函数都会被传入需要格式化的数据,但我的过滤器定义了一个额外的参数,叫做propertyName,我使用他指定将被用于生成唯一值列表的对象属性。在我使用过滤器时,你会看到propertyName参数如何指定该值。该过滤函数的实现很简单:我枚举数据数组的内容并建立属性唯一值的列表,其名称有参数propertyName提供。
tip:我可以把过滤器函数写死如寻找category属性,但那样就局限了在应用程序的其他地方亦或另外的AngularJS应用程序中复用unique过滤器的可能性。我把属性名称作为参数而创建的过滤器可以用于在数据对象集合中生成任何属性的唯一值列表。
过滤函数返回过滤数据是可响应的,即使他无法处理接收的数据。为此,我使用angular.isArray和angular.isString方法检查我用到的数据数组,并且propertyName是字符串。在之后的代码中,我使用angular.isUndefined方法检查属性是否已被定义。
生成分类导航链接
在列表中做的第一个改动是更新sportsStore模块的定义,声明创建的customFilters模块的依赖,它包含unique过滤器:
angular.module("sportsStore", ["customFilters"]);
这就是所谓的声明依赖。这里声明了sportsStore模块依赖于customFilters模块中的功能。这使得AngularJS找到customFilters模块并使之可用,如此我就可以引用他所包含的组件,比如过滤器和控制器,这一过程称为解析依赖。
这里还必须添加script元素以载入包含customFilters模块的文件内容,
<script src="filters/customFilters.js"></script>
注意我可以在sportsStore模块并声明依赖customFilters模块之后,再为customFilters.js文件定义script元素。这是因为AngularJS在使用它们解决依赖之前载入所有模块。效果有些混淆:在你扩展模块时(因为模块必须已经被定义),script元素的顺序很重要,但在定义新模块或声明依赖时不是。
评论