import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { AK, BASE_URL } from '../config';
import * as $ from "jquery";
@Injectable({
providedIn: 'root'
})
export class Http {
constructor(
private http: HttpClient
) {
}
params(data = {}) {
let obj = {...data, ak: AK, output: 'json' };
let paramsStr = '?';
for(let v in obj) {
paramsStr += `${v}=${obj[v]}&`
};
return paramsStr.substr(0, paramsStr.length -1);
}
get(url, params) {
return this.http.get(`${BASE_URL}${url}${this.params(params)}`)
}
getCors(url, params) {
return new Promise((resolve, reject) => {
$.getScript(`${BASE_URL}${url}${this.params(params)}`, (res, status) => {
if(status === 'success') {
resolve(status)
} else {
reject(status)
}
});
})
}
}
定义 jsonp 回调和接收数据变量:
let locationData = null;
window['cb'] = function(data) {
locationData = data && data.results;
}
利用:
async searchLocation(v) {
return await this.http.getCors('/place/v2/search',
{ region:v, query: v, callback: 'cb' });
}
至此,该应用的几大突破点已经解决。接下来,我们来开发项目的核心页面和组件。
• 按需导入组件:
// custom.module.ts
import { NgModule } from '@angular/core';
import { MatButtonModule, MatTooltipModule, MatBadgeModule } from '@angular/material';
@NgModule({
imports: [MatButtonModule, MatTooltipModule, MatBadgeModule],
exports: [MatButtonModule, MatTooltipModule, MatBadgeModule],
})
export class CustomMaterialModule { }
..ts 是根目录中的一个文件。这里我用它作为存放第三方组件的位置。定义好之后,我会在app..ts中引入:
// material组件库
import { CustomMaterialModule } from './custom.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
BrowserAnimationsModule,
ReactiveFormsModule,
AppRoutingModule,
HttpClientModule,
CustomMaterialModule,
],
providers: [],
bootstrap: [AppComponent]
})
ule 主要是一个为组件提供一些动态支持的模块。接下来我们看入口页面:
// app.component.html
为我们定义的app-bar、app-和组件,如下:
// app-bar.html
// app-bar.ts
import { Component, OnInit } from '@angular/core';
import { LocationService } from '../../service/list';
@Component({
selector: 'app-bar',
templateUrl: './index.html',
styleUrls: ['./index.scss']
})
export class AppBar implements OnInit {
items;
constructor(private locationService: LocationService) {
this.items = this.locationService.getItems();
}
ngOnInit() {
}
}
// footer.html
// footer.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-footer',
templateUrl: './index.html',
styleUrls: ['./index.scss']
})
export class AppFooter implements OnInit {
name = '猪先森';
constructor() {
}
ngOnInit() {
}
}
其次,使用了页眉组件,我们来看看这个:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Storage } from './storage';
@Injectable({
providedIn: 'root'
})
export class LocationService {
items = [
{
name: '北京',
desc: '北京好,风景真的不错!',
price: '2000',
date: '2018-12-29',
hasDone: true,
location: {
lat: 39.910924,
lng: 116.413387
}
},
{
name: '苏州',
desc: '苏州好,去了还想去,不错!',
price: '2000',
hasDone: true,
date: '2018-12-29',
location: {
lat: 31.303565,
lng: 120.592412
}
},
{
name: '上海',
desc: '上海好,去了还想去,不错!',
price: '2000',
hasDone: true,
date: '2018-12-29',
location: {
lat: 31.235929,
lng: 121.48054
}
},
{
name: '武汉',
desc: '武汉好,去了还想去,不错!',
price: '2000',
hasDone: true,
date: '2018-12-29',
location: {
lat: 30.598467,
lng: 114.311586
}
}
];
constructor(
private http: HttpClient,
private store: Storage
) {
if(store.get('list')) {
this.items = store.get('list');
}
}
addToList(location) {
this.items.push(location);
this.store.set('list', this.items);
}
getItems() {
return this.items;
}
clearList() {
this.items = [];
return this.items;
}
}
该服务主要提供访问列表、添加旅行列表、清除列表的功能。我们使用@({ : ‘root’ }) 将服务注入根组件以共享服务。其次,我们使用自己封装的服务进行持久数据存储。服务如下:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class Storage {
get(k) {
return JSON.parse(localStorage.getItem(k))
}
set(k, v) {
localStorage.setItem(k, JSON.stringify(v))
}
remove(k) {
localStorage.removeItem(k)
}
}
实现起来比较简单,这里不再赘述。接下来我们看一下首页核心功能的实现:
• 地图初始化路线图:
代码显示如下:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Input } from '@angular/core';
import { Http } from '../service/http';
import { FormBuilder } from '@angular/forms';
import { LocationService } from '../service/list';
@Component({
selector: 'app-home',
templateUrl: './index.html',
styleUrls: ['./index.scss']
})
export class HomeComponent implements OnInit {
hasDoneList;
constructor(
private locationService: LocationService,
private http: Http,
) {
this.hasDoneList = this.locationService.getItems();
}
ngOnInit() {
let map = new BMap.Map("js_hover_map");
// 创建地图实例
map.centerAndZoom(new BMap.Point(118.454, 32.955), 6);
map.enableScrollWheelZoom();
let hasDoneLocations = [];
this.locationService.getItems().forEach(item => {
item.hasDone && hasDoneLocations.push(new BMap.Point(item.location.lng,item.location.lat))
})
let curve = new BMapLib.CurveLine(hasDoneLocations, {strokeColor:"red", strokeWeight:4, strokeOpacity:0.5}); //创建弧线对象
map.addOverlay(curve); //添加到地图中
curve.enableEditing(); //开启编辑功能
}
}
在生命周期中,我们初始化地图数据,根据我们之前定义的列表过滤出真实数据,并显示在地图上。接下来,我们实现添加旅行清单的功能。
添加旅游清单
我们都对表单空间使用 h5 原生控件。我们使用提供的表单模块。具体代码如下:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Input } from '@angular/core';
import { Http } from '../service/http';
import { FormBuilder } from '@angular/forms';
import { LocationService } from '../service/list';
// 获取跨域数据的回调
let locationData = null;
window['cb'] = function(data) {
locationData = data && data.results;
}
@Component({
selector: 'app-home',
templateUrl: './index.html',
styleUrls: ['./index.scss']
})
export class HomeComponent implements OnInit {
hasDoneList;
checkoutForm;
constructor(
private formBuilder: FormBuilder,
private locationService: LocationService,
private http: Http,
) {
this.hasDoneList = this.locationService.getItems();
this.checkoutForm = this.formBuilder.group({
name: '',
price: '',
date: ''
});
}
ngOnInit() {
...
}
async searchLocation(v) {
return await this.http.getCors('/place/v2/search',
{ region:v, query: v, callback: 'cb' });
}
onSubmit(customerData) {
if(customerData.name) {
this.searchLocation(customerData.name).then(data => {
this.locationService.addToList({...customerData, location: locationData[0].location, hasDone: false})
});
} else {
alert('请填写旅游地点!');
return
}
this.checkoutForm.reset();
}
onReset() {
this.checkoutForm.reset();
}
}
// html
我已去过:
未来规划:
我们使用提供的来处理表单数据。这里需要注意的是,我们提交表单的时候,需要调用百度地图的api生成经纬度数据,然后一起添加到列表中。这样做的目的是绘制路线图。您需要向百度地图 API 提供经纬度数据。还有一点,由于访问涉及跨域,我们需要定义jsonp的回调来获取数据,如下:
let locationData = null;
window['cb'] = function(data) {
locationData = data && data.results;
}
的方法会将数据添加到清单中,并将其存储在 . 如果您想知道完整的代码,欢迎您在我的网站上查看。
接下来,看看我的大陆页面。其实涉及的难度并不多,主要是根据真假展示不同的风格。
代码显示如下:
// html
新大陆
新
{{item.name}}
{{item.date}}
{{item.desc}}
预算:{{item.price}}
// ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Input } from '@angular/core';
import { LocationService } from '../service/list';
@Component({
selector: 'app-new-map',
templateUrl: './index.html',
styleUrls: ['./index.scss']
})
export class NewMapComponent implements OnInit {
@Input() product; // 指定product值从父组件中传递
list;
constructor(
private route: ActivatedRoute,
private locationService: LocationService
) {
this.list = locationService.getItems();
}
editItem(item) {
}
ngOnInit() {
this.route.paramMap.subscribe(params => {
// this.product = products[+params.get('productId')];
});
}
}
工程基本完成。如果要查看实际项目效果,可以参考原项目作者的代码:
3.一键云端部署及在线申请1.上传代码
git add .
git commit -m '添加你的注释'
git push
2.日常环境中的部署
一键式应用部署。在应用详情页面,点击日常环境中的“部署”按钮,进行一键部署。部署状态变为绿色并已部署后,您可以点击访问部署网站查看效果。
3.在线环境下配置自定义域名上线
• 为在线环境配置自定义域名。功能开发验证完成后,需要在线环境下进行部署。在线环境的“部署配置”-“自定义域名”中填写自己的域名。比如我们添加一个二级域名..fun来绑定我们部署的前端应用。然后复制自定义域名下的API网关地址,为添加的二级域名配置CNAME。
• 配置CNAME 地址。复制API网关的域名地址后,进入自己的域名管理平台(本例中的域名管理是阿里云的域名管理控制台,请到自己的域名控制台进行操作)。添加记录的“记录类型”选择“CNAME”,在“主机记录”中输入要创建的二级域名,这里我们输入“”,粘贴我们之前复制的API网关域名地址在“记录值”、“TTL”中保留默认值或设置您认为合适的值。
• 在线环境部署上线。回到云开发平台的应用详情页面,按照部署操作,在在线环境中点击“部署按钮”。CNAME生效后,我们输入..fun( URL)打开部署页面。至此,如何将应用部署到在线环境,如何绑定自己的域名访问在线应用就完成了,快速将自己的应用部署到在线环境,玩转自己的域名;)
一键创建应用模板链接:
参考:
暂无评论内容