股票场内基金交易,没时间盯盘?
前提:趣编程的API已经写好。关于API的写法,参见之前的文章(上手第一个API)。本文着重介绍前端Angular2与API的结合。 所需要用到的路由为趣编程admin-api项目里技术类别的列表与添加两个路由。
构建基础页面
代码一般只需要在根目录下src/app/
文件夹下编写即可。首先新建tech-category
目录,在tech-category
目录下新建 index.ts
, tech-category.ts
, tech-categories.component.ts
, tech-category-index.html
, tech-category.service.ts
五个文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
//tech-categories.component.ts文件 import {Component, OnInit} from "@angular/core"; @Component({ selector: 'tech-categories', template: require('./tech-categories.html'), }) export class TechCategoriesComponent implements OnInit { ngOnInit() { console.log('这是技术分类') } } //index.ts文件 export * from './tech-category.component'; //tech-category-index.html <div class="wrapper wrapper-content animated fadeInRight"> <div class="row"> <div class="col-lg-12"> <div class="text-center m-t-lg"> <h1> 这里是技术列表页 </h1> </div> </div> </div> </div> |
接着在下面的文件中写入如下代码(无关代码用省略号代替):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// app.module.ts文件 ...... import { TechCategoryComponent } from './tech-category'; ...... ...... @NgModule({ ...... declarations: [ ...... TechCategoriesComponent ], }) // app.toutes.ts文件 import {TechCategoriesComponent} from './tech-category'; export const ROUTES: Routes = [
{ path: 'tech-categories', component: TechCategoriesComponent }
]; // app/common/navigation/navigation.template.html文件 <li [ngClass]="{active: activeRoute('tech-categories')}"> <a [routerLink]="['./tech-categories']"> <span class="nav-label">技术分类列表</span> </a> </li> |
此时基础的页面应该已经可以成功加载了。
完善技术分类列表
在基础页面搭建完毕后,我们需要将数据显示出来。接下来开始写Service文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// tech-category.ts文件 export class TechCategory { constructor(public name: string,public english_name: string) {} } //这里主要定义返回数据的类型
// tech-category.service.ts文件 import {Injectable} from "@angular/core"; import '../rxjs-operators'; //如果需要用到rxjs库里的内容,请添加到app/rxjs-oprators.ts文件里面 import {Http} from "@angular/http"; import {Observable} from 'rxjs/Observable'; import API_URL from '../config'; //这里是全局配置的测试API地址,如果本地测试可以更改这里的地址为自己的测试地址,提交代码的时候再改回原地址就可以。 @Injectable() export class techCategoryService { constructor(private http: Http) {} getTechCategories(): Observable<any> { return this.http.get(API_URL + '/tech_categories') .map((res: Response) => { return res.json(); }); } }
|
这个Service文件类似于我们在API项目下写的Repository,所有的数据操作都在这里进行,然后在其他地方调用Service来进行数据处理。
因此,在tech-categories.component.ts
中引入这个服务,并进行返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// tech-categories.component.ts文件 import {techCategoryService} from './tech-category.service'; import {TechCategory} from './tech-category'; @Component({ ...... providers: [techCategoryService] }) export class TechCategoriesComponent implements OnInit { techCategories: Array<TechCategory>; //定义返回数据的类型 constructor(private techCategoryService: techCategoryService) {
} ngOnInit() { this.getTechCategories(); }
getTechCategories() { this.TechCategoryService.getTechCategories().subscribe( (data) => { this.techCategories = data.data; }, (error: Object) => { console.log('error!', error); } ); } } |
在component中调用了Service来返回数据,值得一提的是data => { this.techCategories = data.data}
这一行代码,那是因为写好的API返回的是一个Laravel分页数据,在这个数据里面的data才是我们想要的数组,因此是data.data
。
这里只是简单的返回数据,还没有进行分页处理。
接着在tech-category-index.html
里面修改一下代码。
1 2 3 4 5 6 7 8 |
// tech-category-index.html文件 <ul> <li *ngFor="let techCategory of techCategories"> {{techCategory.name}} || {{techCategory.english_name}} </li> </ul> // 这里只是简单的展示数据,并没有进行页面排版,实际操作的时候需要按照要求进行。 |
此时,页面就可以正常展示出我们从API里获取的数据了。
添加技术分类
接着进行添加数据的处理。首先在Service里面添加处理添加数据的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// tech-category.service.ts import {Http, Response, Headers, RequestOptions} from "@angular/http"; export class TechCategoryService { opts: RequestOptions; constructor(private http: Http) { var headers: Headers = new Headers(); headers.append('content-type', 'application/json; charset=utf-8'); this.opts = new RequestOptions(); this.opts.headers = headers; } createTechCategory(techCategory: TechCategory): Observable<Response> { return this.http.post(API_URL +'/tech_categories', techCategory, this.opts); } |
这里就是一个最简单的post请求,具体API的实现去相应的项目里查看。
接着新建tech-category-form.component.ts
,在这个文件里我们来处理相关事宜。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import {Component} from '@angular/core'; import {TechCategory} from './tech-category'; import {TechCategoryService} from './tech-category.service'; @Component({ selector: 'tech-category-form', template: require('./tech-category-form.html'), providers: [TechCategoryService] }) export class TechCategoryFormComponent { model = new TechCategory('', ''); constructor(private TechCategoryService: TechCategoryService) {} createTechCategory(techCategory: TechCategory) { this.TechCategoryService.createTechCategory(techCategory) .subscribe( (data) => { console.log(data); }, (error: Object) => { console.log('error!', error); }); } }
|
新建tech-category-form.html
,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<div class="container"> <h1>技术分类表单</h1> <form (ngSubmit)="onSubmit()" #techCategoryForm="ngForm"> <div class="form-group"> <label for="name">名称</label> <input type="text" class="form-control" id="name" [(ngModel)]="model.name" name="name" #name="ngModel" required> </div> <div class="form-group"> <label for="english_name">英文名称</label> <input type="text" class="form-control" id="english_name" [(ngModel)]="model.english_name" name="english_name" #english_name="ngModel" required> </div> <button type="button" class="btn btn-default" (click)="createTechCategory(model); techCategoryForm.reset()" [disabled]="!techCategoryForm.form.valid">添加 </button> </form> </div>
|
接着新建tech-category-create.component.ts、tech-category-create.html
。
这两个代码很简单。只是一些简单的页面布局和初始化设置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// tech-category-create.component.ts import {Component} from "@angular/core"; @Component({ selector: 'tech-category-create', template: require('./tech-category-create.html'), }) export class TechCategoryCreateComponent { } //tech-category-create.html <div class="text-center m-t-lg"> <tech-category-form></tech-category-form> </div> |
注意到刚才创建的html文件里的<tech-category-form></tech-category-form>
这个自定义标签了么,这个和我们在tech-category-form.component.ts
里的selector是一样的,这样就可以在其他页面里引入写好的form表单页面了。
最后在app.module.ts和app.routes.ts
里面引入刚刚创建的几个Component。基本上就大功告成了。
测试
在列表页我们可以看到数据已经成功添加进来了。
至此,一个基本的列表页和添加页就写成功了。不过,这个代码还是有许多可以惊醒优化和改进的地方。比如错误提示、页面美化等等,这些就需要你们自己来改进啦。
想获得去掉 5 元限制的证券账户吗?

如果您想去掉最低交易佣金 5 元限制,使用微信扫描左边小程序二维码,访问微信小程序「优财助手」,点击底部菜单「福利」,阅读文章「通过优财开证券账户无最低交易佣金 5 元限制」,按照文章步骤操作即可获得免 5 元证券账户,股票基金交易手续费率万 2.5。
请注意,一定要按照文章描述严格操作,如错误开户是无法获得免 5 元证券账户的。
跨域问题:
描述:由于浏览器本身限制,导致无法拿到api返回的数据。
(https://laracasts.com/discuss/channels/requests/laravel-5-cors-headers-with-filters?page=1)提供了各种解决方法。使用Nginx配置可以解决get请求的跨域问题,但是post请求无法解决(和option相关,我也暂时没搞清楚);使用中间件不知道什么原因,一直提示类未定义,最终使用了laravel的CORS插件解决(https://github.com/barryvdh/laravel-cors)
附上相关资料:
CORS(http://www.ruanyifeng.com/blog/2016/04/cors.html)
PS.前前后后因为这个问题折腾了半个多月,解决了之后看过来,走了许多弯路,希望可以帮助到遇到相同问题的小伙伴。有时间会把相关问题总结到博客,可能会详细一点^_^
其实趣编程的API项目已经引入了这个CORS包,后台的API貌似还未处理,能自己解决问题就是一种进步。 继续加油。