收藏
回答

wx.NFCAdapter.onDiscovered()内部监听函数形成闭包?

功能是nfc读取文本后传到后端进行识别跳转页面,现在识别的部分跑通了,但是测试下来发现onDiscovered里面的监听函数的this指向有问题?首次进入页面的时候修改data中的值可以触发watch监听,后续重新切换路由就不触发watch了。

之前试过在onDiscover中调请求方法,然后用this传参,发现也不对,一直沿用第一次成功的参数。

如下是代码截图,我是通过watch监听修改后调接口,然后实现页面跳转的

watch: {
  cleanedcodeDataVal: {
    // immediate:true,
    // deep:true,
    handler(nv, v){
      console.log('cleanedcodeData发生了变化', nv, v);
      if (nv) {
        this.showNFC = false
        this.handleScanLinkToDetail(this.cleanedcodeData, this.actionSheetNfcData)
        this.cleanedcodeData = ''
      } else {
        console.log('cleanedcodeData新值为空', this.cleanedcodeData);
      }
    }
  },
},
handelNfc(item){
  this.actionSheetNfcData = {}
  this.actionSheetNfcData = item
  this.showNFC = true
  // #ifdef MP-WEIXIN
  // 获取nfc实例
  const self = this
  const contentDiscoverHandler = (res) => {
    const byteToString = function (arr) {
      if (typeof arr === 'string') {
        return arr;
      }
      var str = '',
        _arr = arr;
      for (var i = 0; i < _arr.length; i++) {
        var one = _arr[i].toString(2),
          v = one.match(/^1+?(?=0)/);
        if (v && one.length == 8) {
          var bytesLength = v[0].length;
          var store = _arr[i].toString(2).slice(7 - bytesLength);
          for (var st = 1; st < bytesLength; st++) {
            store += _arr[st + i].toString(2).slice(2);
          }
          str += String.fromCharCode(parseInt(store, 2));
          i += bytesLength - 1;
        } else {
          str += String.fromCharCode(_arr[i]);
        }
      }
      return str;
    };
    // console.log('查看nfc感应返回的callback',res.techs,this.nfc.tech);
    // if (res.techs.includes(this.nfc.tech.ndef)) {
    // console.log('符合nfc标准',res.messages)
    let cordsArray = res.messages[0].records;
    // 经常性1次成功,多次空值。所以需要排除
    if (!cordsArray.length > 0) {
      return
    }
    // 准备处理后数据的容器
    let read = {}
    cordsArray.find(item => {
      read.payload = byteToString(new Uint8Array(item.payload));
      read.id = byteToString(new Uint8Array(item.id));
      read.type = byteToString(new Uint8Array(item.type));
    });
    let code = read.payload
    // 去除乱码字符
    let cleanedcode = code.replace(/[^\x20-\x7E]/g, "");
    console.log('nfc读取后获得的code字段==', cleanedcode, this.cleanedcodeData);
    this.cleanedcodeData = cleanedcode
    self.cleanedcodeData = cleanedcode
    console.log('nfc读取后赋值==', this.cleanedcodeData);
  }
  this.nfc.onDiscovered(contentDiscoverHandler)
  this.nfc.startDiscovery({
    fail(err) {
      console.log('failed to discover:', err)
    }
  })
  // #endif
},
  async handleScanLinkToDetail(cleanedcodeData, item){
  const payData = {
    // 如果是详情页的扫码感应,type为detail
    type: 'list',
    content_id: this.contentId,
    fkd_content_id: item.fkd_content_id,
    code: cleanedcodeData
  }
  console.log('请求前检查请求参数', payData);
  // 调取接口获得跳转到详情页所需的data_id
  await this.$http.get('content/scan-code', { params: payData }).then((res) => {
    if (!res.data.success) {
      // 业务失败,错误信息
      uni.showToast({
        title: res.data.message,
        icon: 'error'
      })
    }
    console.log('请求成功返回==', res.data);
    const data_id = res.data.data.id
    if (data_id) {
      this.setLinkToContentName(item.label)
      // 请求成功获取到data_id,可以进行跳转
      uni.navigateTo({
        url: `/pages_1/contentInfo/contentInfo?content_id=${item.fkd_content_id || this.contentId}&data_id=${data_id}&menu_id=${this.menu_id}&parent_menu_id=${this.parent_menu_id}¶meter_value=${this.parameter_id}&isLinkTo=1`
      });
    }
  }).catch((err) => {
    // 请求失败
    // uni.showToast({
    //  icon:'error',
    //  title:this.$t('common.failed')
    // })
  })
},

上面两张真机截图分别是第一次进入,感应成功后触发watch调用请求方法的截图和后续进入,数据赋值但是没有触发watch的情况

最后一次编辑于  2023-11-24
回答关注问题邀请回答
收藏

1 个回答

  • life0080
    life0080
    2023-11-27

    解决了。。。

    根本原因是onDiscover()中的回调函数我没有定义在methods中,导致this出现了问题。

    2023-11-27
    有用 1
    回复
登录 后发表内容