NativeScript 是一款跟 ReactNative 对着怼的移动开发技术,其官方钦定了 Angular2 作为推荐的技术框架,那么如何让在浏览器中运行的 Angular2 Web app 项目与 NativeScirpt 项目共享代码呢?

安装 git

git 是一个好东西,让我们首先来安装他,但与以往的安装方式稍有不同。

以下内容 linuxer 可以忽略

进入 git 官网,下载最新的 git for windows 客户端 https://git-scm.com/

安装过程大多可以无脑下一步,但是在下面的页面中,要注意一下,勾上Enable symbolic links

创建项目仓库

使用 git init 初始化项目仓库,然后编辑 .git/config 文件,将 symlinks=false 改成 symlinks=true

建立项目

使用 angular-cli 与 nativescript-cli 创建项目,建立项目没有特别的地方,安装cli 的说明建立即可,使目录结构如图所示:

│  .gitignore

├─mobile
│ │ package.json
│ │ references.d.ts
│ │ tsconfig.json
│ │
│ ├─app
│ │
│ ├─hooks
│ │
│ ├─node_modules
│ │
│ └─platforms

└─web
│ .editorconfig
│ angular-cli.json
│ karma.conf.js
│ package.json
│ protractor.conf.js
│ README.md
│ tslint.json

├─e2e

├─node_modules

└─src

建立共享代码文件夹

在 web/src/app 中建立 x-shared 文件夹,表示 cross-platform-shared 的意思。

然后,cd 到 mobile/app 文件夹中,以管理员身份运行命令行(cmd)并输入:

mklink /d x-shared ..\..\web\src\app\x-shared

这样我们就使用软链接建立一个共享文件夹

linuxer 请使用 ln 命令建立软链接

然后在任意一个 x-shared 文件夹中建立需要跨平台共享的代码文件,比如负责 http 请求的 service,这里我来做个示例:

// account.service.ts

import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Injectable } from '@angular/core'; // rxjs
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map'; import { LoginResult } from '../models/login-result';
import { ErrorJson } from '../models/error';
import { Config } from '../config'; @Injectable()
export class AccountService {
private loginUrl = Config.baseUrl + 'api/account/login'; /**
* 登录!
*/
constructor(private http: Http) {
} /**
* 解析消息
*
* @private
* @param {Response} res
* @returns {LoginResult}
*
* @memberOf AccountService
*/
private extractData(res: Response): LoginResult {
let body = res.json();
return <LoginResult>body;
} /**
* 错误处理,将错误消息返回,消息形式:错误代码 - 错误详情
*
* @private
* @param {(Response | any)} error
* @returns
*
* @memberOf AccountService
*/
private errorHandler(error: Response | any) {
let errMsg: string;
if (error instanceof Response) {
const body = <ErrorJson>error.json();
errMsg = `${body.errorMsg}`;
} else {
errMsg = error.toString();
}
console.log('errMsg');
return Observable.throw(errMsg);
} /**
* 用户登录
*
* @param {string} usr 用户名
* @param {string} pwd 明文密码
* @returns 登录结果
*
* @memberOf AccountService
*/
login(usr: string, pwd: string) {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers }); let data = {
userName: usr,
password: pwd
}; return this.http.post(this.loginUrl, data, options)
.map(this.extractData)
.catch(this.errorHandler);
}
}

然后分别在两个项目中引用这个 service。

调用共享的 Service

就像原先一样来引用共享的 service

// web 版的登录入口

import { Component, OnInit } from '@angular/core';

import { AccountService, LoginResult, ErrorJson } from 'x-shared'; // 就像原先一样来引用共享的 service

import { LocalNoticeService, LocalNoticeType } from 'shared/notice.service';

@Component({
selector: 'nav-account',
templateUrl: './nav-account.component.html',
styleUrls: ['./nav-account.component.css'],
providers: [AccountService]
})
export class NavAccountComponent implements OnInit { constructor(
private account: AccountService,
private localNoticeService: LocalNoticeService // 这是在网页弹窗的消息服务
) {
} login(usr: string, pwd: string) {
if (usr === '' || pwd === '') {
// 在网页上显示一个提醒
this.localNoticeService.showMsg('登录失败', '请输入用户名和密码!', LocalNoticeType.error);
return;
}
// 跨平台的登录功能
this.account.login(usr, pwd)
.subscribe(
(res: LoginResult) => {
this.localNoticeService.showMsg('登录成功', '', LocalNoticeType.success);
},
(error: string) => {
this.localNoticeService.showMsg('登录失败', error, LocalNoticeType.error);
});
} ngOnInit() { }
}
// 手机上面的登录页面

import { Component, OnInit } from '@angular/core';
import * as dialogs from 'ui/dialogs'; import { AccountService, LoginResult } from '../../x-shared'; // 就像原先一样来引用共享的 service @Component({
selector: 'login',
templateUrl: './pages/login/login.component.html',
providers: [AccountService]
}) export class LoginComponent implements OnInit { constructor(private account: AccountService) { } ngOnInit() { } login(usr: string, pwd: string) {
if (usr === '' || pwd === '') {
// 调用原生的 API 弹窗提示
dialogs.alert({
message: '请填写用户名和密码!',
okButtonText: '确定'
});
return;
}
// 跨平台的登录功能
this.account.login(usr, pwd)
.subscribe(
(res: LoginResult) => {
let options: dialogs.AlertOptions = {
title: '登陆成功',
message: `${res.token.authToken}
${res.token.refreshToken}`,
okButtonText: '确定'
};
dialogs.alert(options).then(() => console.dir(res));
},
(err: string) => {
let options: dialogs.AlertOptions = {
title: '登陆失败',
message: err,
okButtonText: '确定'
};
dialogs.alert(options);
});
}
}

效果!

web 网页

手机移动端

至此,我们就实现了网页版与手机客户端共享一套代码的功能,一旦 service 需要发生变动,只需要更改任意一个 x-shared 文件夹的代码,更改就会同时作用到另一个项目上。

注意!

  • 在 windows10 创造者更新之前,创建软链接需要管理员权限,请确保通过使用带有管理员权限的命令行来克隆仓库

  • windows 下的软链接只在 Vista 以上的 windows 系统中起作用

Angular2 + NativeScript 跨平台开发笔记(一)的更多相关文章

  1. CoolBlog开发笔记第2课:搭建开发环境

    教程目录 1.1 CoolBlog开发笔记第1课:项目分析 前言 今天是CoolBlog开发笔记的第2课,我们将要讲解的是开发环境的搭建.俗话说"工欲善其事必先利其器",Djang ...

  2. Linux及Arm-Linux程序开发笔记(零基础入门篇)

    Linux及Arm-Linux程序开发笔记(零基础入门篇)  作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/bee ...

  3. Vakuum开发笔记01 开天辟地

    1.缘起 先驱--COGS 早在2008年,我自学PHP后开发了COGS,并成功用于学校内部的OJ,ruvtex.也曾经对外开放过,但是由于学校网络不稳定,后来一直连不上了.我还把COGS推荐给了OO ...

  4. [Openwrt 项目开发笔记]:Samba服务&vsFTP服务(四)

    [Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 在上一节中,我们讲述了如何在路由器上挂载U盘,以 ...

  5. Java开发笔记(一百二十六)Swing的窗口

    前面介绍了AWT界面编程的若干技术,在编码实践的时候,会发现AWT用起来甚是别扭,它的毛病包括但不限于下列几点:1.对中文的支持不好,要想在界面上正常显示汉字,还得在运行时指定额外的运行参数“-Dfi ...

  6. 【Linux开发】Linux及Arm-Linux程序开发笔记(零基础入门篇)

    Linux及Arm-Linux程序开发笔记(零基础入门篇) 作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/beer ...

  7. SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  8. C#移动跨平台开发(2)Xamarin移动跨平台解决方案是如何工作的?

    概述 上一篇 C#移动跨平台开发(1)环境准备发布之后不久,无独有偶,微软宣布了开放.NET框架源代码并且会为Windows.Mac和Linux开发一个核心运行时(Core CLR),这也是开源的!I ...

  9. Visual Studio 2015 移动跨平台开发初体验

    微软换了新 CEO 后变化很大,对我们团队最有利的消息就是 Visual Studio 2015 支持移动应用跨平台开发. 还记不记得很早之前,Xamarin 宣布与微软成为合作伙伴的消息.显然,Xa ...

随机推荐

  1. K-Means算法

    K-Means算法 K-Means算法的输入N,K和一个size为N的向量组vector.输出K个两两互不相交的向量组.其本质是将给定的向量组划分成K个类别,使得同类别的向量相似度比较大,而不同类别的 ...

  2. 强烈推荐:240多个jQuery插件【转】

    强烈推荐:240多个jQuery插件 概述 jQuery 是继 prototype 之后又一个优秀的 Javascript 框架.其宗旨是—写更少的代码,做更多的事情.它是轻量级的 js 库(压缩后只 ...

  3. 简单的HTTP过滤模块

    简单的HTTP过滤模块 一.Nginx的HTTP过滤模块特征 一个请求可以被任意个HTTP模块处理: 在普通HTTP模块处理请求完毕并调用ngx_http_send_header()发送HTTP头部或 ...

  4. sql 数据库还原脚本 (kill链接+独占

    在开发过程中经常会碰到数据库还原,要是sql 连接没完全释放掉,那么还原就会受到阻碍.此脚本就是为了解决这个问题. USE [master] GO /****** Object: StoredProc ...

  5. 一点MongoDB的基础及mongodb在mac上的安装

    最近发现维持写博客的习惯还是挺困难的,尤其对我来说,计划好的事过了好长时间才想到要去做. 这段时间一直在熟悉MongoDB,首先我是参考的这一篇:8天学通MongoDB   原博主写得非常好,我这里就 ...

  6. grub 的安装与使用

    安装与使用grub 要开始探究 GRUB 的精妙之处,首先需要下载.编译和安装它.但不要害怕 -- 根本不会修改您的引导记录 -- 我们只是要编译和安装 GRUB,就像其它程序一样,在此过程中我们可以 ...

  7. JDBC--手动开启Connection事务

    三层架构中的业务逻辑层是处理业务逻辑的部分,很多时候需要调用多步Dao层的增删改操作,这就涉及到使用事务保证数据的一致性. Connection接口自带的事务机制需要保证多步SQL操作使用相同的连接对 ...

  8. 编程利用利用curses库编程开始

    时间紧张,先记一笔,后续优化与完善. curses库常用函数: 注意编译时要用这样的格式:gcc xxx.c -l curses -o xxx 第一个小例子: include <stdio.h& ...

  9. 在React+Babel+Webpack环境中使用ESLint

    ESLint是js中目前比较流行的插件化的静态代码检测工具.通过使用它可以保证高质量的代码,尽量减少和提早发现一些错误.使用eslint可以在工程中保证一致的代码风格,特别是当工程变得越来越大.越来越 ...

  10. javascript提高篇+吐槽

    开篇吐槽 最近一直在投简历找工作,对于博主这样的屌丝应届生来说,一没过硬的技术,二没经验,三没高学历,四没炫酷的项目,五还没漂亮的简历,简直就是3无产品+2b青年.所以快1个月了投的简历没有收到一个面 ...