zoukankan      html  css  js  c++  java
  • ionic2+Angular web端 实现微信分享以及如何跳转回分享出去的页面

    微信分享,首先参考微信JS-SDK开发文档

    step1:在启动文件index.html中引入微信js文件;

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

    step2:微信config接口注入权限验证配置。新建wechat.service.ts文件进行相关配置。文件建好之后在app.module.ts文件中引入WechatService,程序中的所有页面都能使用该服务,不需要逐个页面引入服务。

     

    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,并在需要分享的页面继承;

    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:分享出去的效果

     以上,微信分享到“微信朋友”完成。


     接下来是,点击分享出去的连接,如何正确跳转到指定的页面。

    //分享出去的连接

    //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; } } }
  • 相关阅读:
    10、HTTP请求方法你知道多少?
    9、为什么服务器会缓存这一项功能?如何实现的?
    7、HTTP长连接和短连接的区别 8、什么是TCP粘包/拆包?发生的原因?
    zzulioj--1719--小胖的疑惑(整数划分+dp打表)
    nyoj--27--水池数目(dfs)
    hdoj--1016--Prime Ring Problem(递归回溯)
    zzulioj--1777--和尚特烦恼3——何时能下山(水题)
    zzulioj--1708--01串也疯狂之光棍也有伴(dp)
    zzulioj--1707--丧心病狂的计数(水题)
    zzulioj--1711--漂洋过海来看你(dfs+vector)
  • 原文地址:https://www.cnblogs.com/tomboyxiao/p/7521576.html
Copyright © 2011-2022 走看看