1. JavaScript 的几个注意点
1.1. 理解 function
- function所定义的变量是一个function类型的实例。
- function就像Java或者C++中的class一样,其所定义的实例,是一种用户定义的类型。这种类型的构造函数可以被当作普通函数调用。
作普通函数调用时
function a(){
alert("Yes");
}
a();
作类型使用时
function GreatMan(){
this.name = "毛主席"; //(1)
this.speak = function(){ //(2)
alert("同志们辛苦了!");
}
}
GreatMan.will = "意志力!"; //(3)
GreatMan.prototype.command="进军"; //(4)
GreatMan.prototype.order = function(){ //(5)
alert(this.command);
}
var p = new GreatMan(); //(6)
p.speak(); //(7)
p.order();
(1) 定义成员变量方法1.
(2) 定义成员函数方法1.
(2) 定义静态变量方法1. 放在函数体内也可以。
(4) 定义成员变量方法2.
(5) 定义成员函数方法2
(6) 创建一个GreatMan类型的实例。注意不可以使用 GreatMan man; 这种形式来定义。
(7) 调用自己的成员函数
1.2. JSON风格成员变量定义
普通对象和其成员变量定义
var a = {
key1: 0,
key2: "123",
key3: 1.2
};
alert(a.key2);
函数型类型的体外成员变量定义:
function B(){
}
B.prototype={
key4:4,
key5:-2
};
var b = new B();
alert(b.key5);
实际代码片段:
BaseEnrollmetCtrl.prototype = {
getBaseInfoEnums: function () {
var self = this;
self.SubmitService.getBaseInfoEnums().then(function (data) {
self.$scope.submitTask = data.submitTask;
self.$scope.eventTypeList = data.submitType;
});
},
getCategories: function () {
...
1.3. call() 和 apply() 函数
定义:
call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
用法:
function Dog(){
this.name = "Dog";
this.showName = function(){
alert(this.name);
}
}
function Cat(){
this.name = "Cat";
}
var dog = new Dog();
var cat = new Cat();
dog.showName.call(cat);
apply 用法:
/*定义一个人类*/
function Person(name,age)
{
this.name=name;
this.age=age;
}
/*定义一个学生类*/
function Student(name,age,grade)
{
Person.apply(this,arguments); //(1)
this.grade=grade;
}
//创建一个学生类
var student=new Student("qian",21,"一年级");
//测试
alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);
//测试结果name:qian age:21 grade:一年级
(1) arguments 代表将本函数的参数和Person的参数按照顺序一一对应并且完成赋值。
1.4. concat函数
[].concat(arrayX,arrayX,......,arrayX)
2. Gmkt-portal-web中JS代码组织结构
2.1. 服务器数据获取
js/services/*
2.2. 模块数据定义
js/controllers/*base*.js
js/services/data-types.js
2.3. 模块页面控制器
js/controllers/*/*
2.4. 视图和模型
视图-> 视图模型->服务器契约模型->服务器。
2.5. vm变量的使用
想象一样,用户切换了页面,如果获取新页面对应控制器的变量呢?
- 使用新页面对应的控制器来访问,比如切换到AController,访问a变量时,用AController.a。
- 在切换动作发生时,将控制器统一赋值给一个变量c,访问a变量时,用c.a。
方法比较:个人觉得第二种一旦切换时,由于未知因素导致失败后,vm将乱序,导致整个页面出错,而且统一使用vm,有一个额外的理解成本,多了之后会混淆。所以推荐使用第一种。但是我们的项目里使用了第二种:
.state('activity.enrollment', {
url: '/enrollment',
views: {
'content@activity': {
templateUrl: '/pages/enrollment/list.html',
controller: 'EnrollmentListCtrl',
controllerAs: 'vm'
}
},
ncyBreadcrumb: {
label: '地区活动列表'
}
})
上述语法的含义是:当页面导向到/enrollment的时候,把EnrollmentListCtrl控制器赋值给vm,这样使用vm.xxx就可以访问EnrollmentListCtrl控制器里定义的变量了。
3. 具体改动注意点
3.1 添加无预算活动屏蔽校验
- enroll-deal.html中找到
<div ng-if="vm.eventInfo.taskType <31 || vm.eventInfo.taskType>35"
这句,代表在[31,35]内的活动类型,可以直接提交,不需要设置优惠金额等。 - task-types.js 文件中找到
else if (type >=31 && type <=35) return this.FreeEntertainment;
这句,代表在[31,35]内的活动类型使用FreeEntertainment表格配比类型。
3.2 二级类目联动(你一定会发现这个部分很有用!)
js/controllers/submit/base.js 相关数组定义
this.$scope.poiMainCategories = []; // POI一级类目
this.$scope.poiSubCategories =[]; // POI二级类目数组
this.$scope.currentPoiSubCategories = [];// 当前POI二级的类目
js/controllers/submit/base.js:相关数据初始化
getCategories: function () {
var self = this;
self.SubmitService.getCategories().then(function (data) {
...
//团购POI二级类目联动所需数据
for(var p = 0; p < data.poiMainCategories.length; p++)
{
var data_item = data.poiMainCategories[p];
var local_item = {
code: data_item.code,
desc: data_item.desc
};
self.$scope.poiMainCategories.push(local_item);
self.$scope.poiSubCategories[data_item.code]= data_item.subCategories;
}
self.$scope.currentPoiSubCategories = [];
...
});
}
js/services/submit.js:远程数据获取
getCategories: function () {
return $http.get('/submit/getCategories')
},
SubmitController:JAVA服务端数据返回
@RequestMapping("getCategories")
@ResponseBody
public SalesPortalResponse<CategoriesAllInOne> getCategories() {
return SalesPortalResponse.success(submitEnrollmentService.getCategoriesAllInOne());
}
其中getCategoriesAllInOne()的实现(片段)为:
public CategoriesAllInOne getCategoriesAllInOne()
{
CategoriesAllInOne result = new CategoriesAllInOne();
...
List<CategoryItem> poiSubCategories1 = new ArrayList<CategoryItem>();
poiSubCategories1.add(new CategoryItem(0,"POI子类别-1-1"));
poiSubCategories1.add(new CategoryItem(1,"POI子类别-1-2"));
List<CategoryItem> poiSubCategories2 = new ArrayList<CategoryItem>();
poiSubCategories2.add(new CategoryItem(0,"POI子类别-2-1"));
poiSubCategories2.add(new CategoryItem(1,"POI子类别-2-2"));
List<CategoryData> poiMainCategories = new ArrayList<CategoryData>();
poiMainCategories.add(new CategoryData(0,"POI主类别-1",subCategories1));
poiMainCategories.add(new CategoryData(1,"POI主类别-2",subCategories2));
result.setPoiMainCategories(poiMainCategories);
...
return result;
}
submit-rule-config.html: 页面部分
<div class="col-xs-12 no-padding">
<font class="fs_15"> POI类别: </font>
<ui-select ng-model="tuangouSubmitRule.poiMainCategory" ng-disabled="editable" ng-change="changePoiSubCategory()">
<ui-select-match placeholder="请选择主类目...">{{$select.selected.desc}}
</ui-select-match>
<ui-select-choices repeat="item in poiMainCategories">
<span ng-bind-html="item.desc | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
<ui-select ng-model="tuangouSubmitRule.poiSubCategory" ng-disabled="editable">
<ui-select-match placeholder="请选择子类目...">{{$select.selected.desc}}
</ui-select-match>
<ui-select-choices repeat="item in currentPoiSubCategories">
<span ng-bind-html="item.desc | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
</div>
js/controllers/submit/base.js:当下拉框变化时触发
this.$scope.changePoiSubCategory = function () {
self.$scope.currentPoiSubCategories = self.$scope.poiSubCategories[self.$scope.tuangouSubmitRule.poiMainCategory.code];
};
网友评论