ionic2+Angular web端 實現微信分享以及如何跳轉回分享出去的頁面

微信分享,首先參考微信JS-SDK開發文檔php

 

 

step1:在啓動文件index.html中引入微信js文件;html

 <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

 

 

step2:微信config接口注入權限驗證配置。新建wechat.service.ts文件進行相關配置。文件建好以後在app.module.ts文件中引入WechatService,程序中的全部頁面都能使用該服務,不須要逐個頁面引入服務。json

 

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { URLService } from './urls';
import { WechatShareModel } from '../model-res/wechat-share-model';
import { Observable, Subscriber } from 'rxjs';
import { CommonService } from './common.service';

declare var wx: any;
@Injectable()
export class WechatService {
    constructor(
        private http: Http,
        private us: URLService,
        private cs: CommonService,
    ) { }


    jfOnMenuShareAppMessage(shareData?: WechatShareModel) {
        if (!shareData) {
            shareData = new WechatShareModel();
        }
        let shareD = {
            title: shareData.title, // 分享標題
            desc: shareData.desc, // 分享描述
            link: shareData.link, // 分享連接
            imgUrl: shareData.imgUrl, // 分享圖標
            type: shareData.type, // 分享類型,music、video或link,不填默認爲link
            dataUrl: shareData.dataUrl, // 若是type是music或video,則要提供數據連接,默認爲空
            success: function () {
                // 用戶確認分享後執行的回調函數
            },
            cancel: function () {
                // 用戶取消分享後執行的回調函數
            }
        }
        wx.onMenuShareAppMessage(shareD);
    }

    getWechatConfigFun(): any {
        //便於PC端調試
        return new Observable(x => this.getWechatConfig(x));

        //正式上線
        // if (this.cs.IsWeChatFun()) {//判斷是不是微信瀏覽器
        //     return new Observable(x => this.getWechatConfig(x))
        // } else {
        //     return new Observable(x => x.next('非微信瀏覽器!'))
        // }
    }

    private getWechatConfig(x: Subscriber<any>) {
        let wechatUrl = location.href.split('#')[0];
        //使用encodeURIComponent()的緣由請參考 附錄4-常見錯誤及解決方法
        let url = this.us.getUrl('wechatConfig', { url: encodeURIComponent(wechatUrl) });
        this.http.get(url).subscribe(res => {
            let configData = res.json().data;//處於安全考慮timestamp、nonceStr、signature等信息在服務器端處理。
            delete configData['url'];
            configData['appId'] = 'wx8888888888888888';
            configData['debug'] = false;//開啓調試模式,調用的全部api的返回值會在客戶端alert出來.
            configData['jsApiList'] = ['onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareTimeline', 'onMenuShareWeibo', 'onMenuShareQZone'];
            wx.config(configData)//config接口注入權限驗證
            wx.ready(() => {
                x.next(200);
            })
            wx.error((res) => {
                x.next('微信配置錯誤');//配置失敗,返回錯誤信息均可以查看微信文附錄4-常見錯誤及解決方法
            })
        }, () => {
            x.next('微信權限驗證配置API鏈接錯誤!');
        })
    }
}

 

setp3:新建main.ts,並在須要分享的頁面繼承;api

import { ViewChild } from '@angular/core';
import { Content, Footer } from 'ionic-angular';
import { WechatService } from './wechat.service';
import { WechatShareModel } from '../model-res/wechat-share-model';
export class MainPage { @ViewChild(Content) content: Content; @ViewChild(Footer) footer: Footer; shareDatas: WechatShareModel
= null;//存儲當前頁面須要分享的相關信息 timer; downTime = 0;//若是當前頁面30秒後認爲設置分享數據,則使用默認分享數據 constructor(public wechat: WechatService) { }//wechat須要聲明public才能繼承,繼承該文件的頁面也須要聲明public的wechat ionViewDidEnter() { //二級頁面繼承MainPage //二級頁面刷新處理start let tabbarEles = document.querySelectorAll(".tabbar"); Object.keys(tabbarEles).map((key) => { tabbarEles[key].style.zIndex = '0';//二級頁面不顯示tabs,由於ionic2模式下刷新當前頁面是會出現tabs底部導航 }); this.content._scrollContent.nativeElement.style.marginBottom = '0px'; if (this.footer) { //若是二級頁面存在底部自定義按鈕 //須要調整文本content的margin-bottom //須要調整footer距離底部的位置 this.footer._elementRef.nativeElement.style.bottom = '0px'; this.content._scrollContent.nativeElement.style.marginBottom = '50px'; } //二級頁面刷新處理end //ionViewDidEnter()中進行微信API接口的配置; //①每次進入頁面都會執行,保證每一次的分享數據的實時更新。避免分享的數據是以前訪問的頁面數據 this.ngAfterShare(); } ionViewWillLeave() { //離開頁面以前對tabs的處理,要否則返回以後沒有底部導航 let tabbarEles = document.querySelectorAll(".tabbar"); Object.keys(tabbarEles).map((key) => { tabbarEles[key].style.zIndex = '10';//離開頁面以前撤銷刷新頁面以後的修改。 }); if (this.timer) { clearInterval(this.timer) } } ngAfterShare(pageISNoReload?: boolean) { let $this = this; if (pageISNoReload) {
//部分頁面沒有跳轉,直接在當前頁面獲取新的數據時候也須要設置新的分享數據。
//使用場景
//例如:商品搜索頁面,頁面進行在次搜索,或者點擊分類篩選等,避免分享的數據是最初的數據,須要實時更新分享數據
//搜索頁面點擊搜索,更新分享連接 $this.wechat.getWechatConfigFun().subscribe(res2 => { //避免沒有獲取到數據的使用默認設置的分享數據 if (res2 == 200) { $this.wechat.jfOnMenuShareAppMessage(this.shareDatas); } }) } else { //使用setInterval()反覆進行微信配置,主要是頁面獲取數據存在異步。 this.timer = setInterval(() => { $this.downTime += 1; if ($this.downTime >= 30) { $this.shareDatas = new WechatShareModel();//設置默認分享的數據 } console.log('titmer'); if ($this.shareDatas) { //設置完成當前頁面的分享數據 if ($this.timer) { clearInterval($this.timer); } //進行微信config的配置 $this.wechat.getWechatConfigFun().subscribe(res2 => { //避免沒有獲取到數據的使用默認設置的分享數據 if (res2 == 200) { let link = ''; if (location.href.indexOf('params') > -1) { let params = location.href.split('#')[1]; //避免從分享出去的入口進入再分享。
//須要從新設置分享的鏈接
//
link = location.href.split('?params')[0] + '?params=' + params; } else {
//例如當前頁面hash格式:http://m.hxyxt.com/www/#/tabs/t0/%E7%A7%AF%E5%88%86%E5%95%86%E5%9F%8E/jfProduct/100017632
//微信配置中會自動過濾掉#號後邊的地址,因此須要須要將#好後邊的url做爲參數設置成當前頁面的分享地址;
//
link
= location.href.split('#')[0] + '?params=' + location.href.split('#')[1];
//從新拼接的地址:http://m.hxyxt.com/www/?params=/tabs/t0/%E7%A7%AF%E5%88%86%E5%95%86%E5%9F%8E/jfProduct/100017632 }
if (!$this.shareDatas.link) { $this.shareDatas.link = link; } $this.wechat.jfOnMenuShareAppMessage($this.shareDatas); } }) } }, 1000) } } }

 

如下是默認的分享模板瀏覽器

export class WechatShareModel {
    title: string = ''  // 分享標題
    desc: string = ''  // 分享描述
    link: string = ''  // 分享連接
    imgUrl: string = ‘’;  //分享圖片
    type: string = ''  // 分享類型 music、video或link,不填默認爲link
    dataUrl: string = ''  // 若是type是music或video,則要提供數據連接,默認爲空
}

 

 

 

 

step4:在須要設置分享的頁面繼承MainPage。以商品詳情頁面爲例。安全

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { JfProductService } from './jf-product.service';
import { ProductLunboslideshowModel } from '../../model-res/jf-home-model';
import { CommonService } from '../../common/common.service';
import { MsgBarService } from '../../common/msg-bar';
import { MainPage } from '../../common/main';
import { WechatService } from '../../common/wechat.service';
import { UserService } from '../user/user.service';

@IonicPage({
  name: 'jfProduct',
  segment: 'jfProduct/:p0',
  defaultHistory: ['jfHome']
})
@Component({
  selector: 'page-jf-product',
  templateUrl: 'jf-product.html',
})
export class JfProductPage extends MainPage {//繼承MainPage
  lunboHeight;//輪播高度與屏幕寬度一致;
  buyNum: number = 1;//記錄兌換的數量
  infos;
  pID: any;
  slidesImgs: ProductLunboslideshowModel[] = [];
  myIntergral: number = this.cs.getMyIntergral();

  constructor(
    private cs: CommonService,
    private service: JfProductService,
    public navCtrl: NavController,
    public navParams: NavParams,
    private ms: MsgBarService,
    public wechat: WechatService,//
    private us: UserService) {
    super(wechat);//繼承須要寫入該方法。 this.lunboHeight = window.innerWidth;
    this.pID = navParams.data.p0;
  }


  getProduct(e?) {
    let loading = this.ms.loading('正在獲取商品數據……');
    loading.present();
    this.service.getIntegralProductDetail({ productCode: this.pID }).subscribe(res => {
//獲取商品詳情結束 loading.dismiss();
this.infos = res; this.slidesImgs = new Array(); res.images.forEach((v, i) => { if (v.imageType == 'GALLERY' && v.format == 'superZoom') { let img: ProductLunboslideshowModel = { code: '', url: v.url, type: '' } this.slidesImgs.push(img); } }); if (e) { e.complete(); } //設置當前頁面的分享數據 start this.shareDatas = { title: '小夥伴,快來看看吧,【' + res.name + '】', desc: '只要【' + res.integral + '積分+' + res.vipPrice + '元】便可兌換!', link: '',//連接地址在MainPage的分享配置中統一設置 imgUrl: res.images[0].url, type: '', dataUrl: '', }
      //設置當前頁面的分享數據 end
    }, () => {
      loading.dismiss();
      if (e) { e.complete(); }
    })
  }
}

 

 

step5:在微信中查看商品詳情並分享給微信朋友。服務器

                        

 

step5:分享出去的效果微信

 

 以上,微信分享到「微信朋友」完成。session

 

 

 


 

 接下來是,點擊分享出去的鏈接,如何正確跳轉到指定的頁面。app

//分享出去的鏈接

//http://m.hxyxt.com/www/?params=/tabs/t0/%E7%A7%AF%E5%88%86%E5%95%86%E5%9F%8E/jfProduct/100017234

 //點擊分享出去的鏈接,都是默認跳轉到程序的默認啓動頁面,如商城首頁。因此須要在該頁面解析。


方法1:在頁面初始化時調用如下的方法(建議先往下看

isShareView() {
    if (this.ls.retrieve('SHAREURLLOADED') && this.isLogin) {
      let params=this.ls.retrieve('SHAREURLLOADED');
      this.ls.clear('SHAREURLLOADED');
          window.location.href=location.href.split('#')[0]+params;
    }

    if (location.href.indexOf('params') > -1) {
      //存在該參數說明是分享出去的鏈接
      let $this = this;
      setTimeout(() => {
        //須要進行必定的延時
        let url = location.href;
        url = url.replace('?params=', '#');
        url = url.split('#')[0];
        console.log(location);
        let params = location.search;//獲取頁面參數部分
        params = params.replace('?params=', '#');//解析成ionic路徑格式
        console.log(params);
        //在LocalStorageService中存入該參數
        this.ls.store('SHAREURLLOADED', params);
        window.location.replace(url);//重構當前頁面url,爲了跳轉以後能回到首頁
      }, 500)
    }
  }

弊端:直接改變頁面路徑會致使APP重啓,會看到兩次啓動頁面。用戶體驗不是很好。

優勢:分享商品的link配置比較方便,不要再處理。

 

方法2:在頁面初始化時調用如下的方法

 

isShareView() {

    if (this.ss.retrieve('SHAREURLLOADED')) {
      return;
    }

    if (location.href.indexOf('params') > -1) {
      //分享出去的鏈接
      let $this = this;
      setTimeout(() => {
        //須要進行必定的延時
      
        let params = location.search;
        params = params.substring(params.lastIndexOf('params'))
        params = params.replace('params=/', '');
        let para = params.split('/');
        let gotoUrl = para[3];
        let gotoParamsArr = new Array();
        para.forEach((v, i) => {
          if (i > 3) { gotoParamsArr.push(v) }
        });
        let gotoParamsObj = {};
        gotoParamsArr.forEach((v, i) => {
          let item = 'p' + i;
          gotoParamsObj[item] = v;
        });
        if ($this.isLogin) {
          //若是存在LocalStorageService的話,再次進入也不會跳轉到分享出去的頁面,因此存在session 
$this.ss.store('SHAREURLLOADED', true);//標識用戶是否已經跳轉過度享出去的頁面。//避免頁面刷新重複看到應用啓動的效果。
$this.navCtrl.push(gotoUrl, gotoParamsObj);//解析成爲頁面跳轉須要的數據格式。
}
},
500) }
}

 

弊端:須要在分享配置link的時候進行url中的參數處理,不然分享出去的鏈接會存在多個params;

優勢:①進入頁面以後根據分享獲得的鏈接進行解析,轉成ionic跳轉頁面須要的格式。

②不更改頁面路徑,不會出現從新加載的啓動畫面。

③頁面實現跳轉比較平穩,用戶體驗效果更好。

 

 

20170920:補充頁面解析參數的方式

isShareView() {
    let paramsString = location.search; let searchParams = new URLSearchParams(paramsString); if (this.ss.retrieve('SHAREURLLOADED')) {
      return;
    }

    if (searchParams.has("params") === true) {
//分享出去的鏈接
      let $this = this;
      setTimeout(() => {
        //須要進行必定的延時
      let params = searchParams.get("params").split('/')
    let navPush = params[3];//要跳轉的頁面
    let navParams = new Array();
    params.forEach((v, i) => {
      if (i > 3) { navParams.push(v) }
    });
    let navParamsObj = {};//拼接成要轉規定的參數模式
    navParams.forEach((v, i) => {
      let item = 'p' + i;
      navParamsObj[item] = v;
    });
    if (this.isLogin) {
      if (navPush == 'usercenter') {
        //導航頁面
        this.navCtrl.parent.select(3);
        this.navCtrl.popToRoot();
      } else {
        //二級頁面
        //若是存在Local的話,再次進入也不會跳轉到分享出去的頁面,因此存在session
        this.ss.store('SHAREURLLOADED', true);//標識用戶是否已經跳轉過度享出去的頁面。//避免頁面刷新重複看到應用啓動的效果。
        this.navCtrl.push(navPush, navParamsObj);//解析成爲頁面跳轉須要的數據格式。
      }
    }
  
 }, 500) } 
}

 

 

20170927:補充

import { Injectable } from '@angular/core';
import { URLSearchParams } from '@angular/http';
class environment {
    static yxt = 'https://www1.hxyxt.com/';//正式環境
}

const URLS = {
    'wechatConfig':'http://vipapi.yxtmart.cn/SIGN?url={url}',//獲取微信配置的數據
}

@Injectable()
export class URLService {


    constructor() { }

    getUrl(pathName: string, ...args) {
//頁面請求的參數處理
let reg = /^(http|https):\/\//; let isUrl = reg.test(pathName) if (isUrl && args.length == 0) return pathName; pathName = isUrl ? pathName : URLS[pathName]; var url = pathName;for (var key in args[0]) { url = url.replace(`{${key}}`, args[0][key]); } return url; } objectToUrlParams(obj) { var paras = new URLSearchParams(); for (var key in obj) { var element = obj[key]; paras.append(key, element) } return paras; } }

 

 

import { Injectable } from '@angular/core';

@Injectable()
export class CommonService {
    constructor() { }

    IsWeChatFun() {
//判斷是否在微信端 let ua
= window.navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i)) { return true; } else { return false; } } }
相關文章
相關標籤/搜索