微信小程序selectComponent返回null的问题排查与分析-程序员宅基地

技术标签: 自定义组件引用为null  selectComponent返回unll  selectComponent  自定义组件  小程序  

       要想小程序界面好看,还原UI妹纸设计的界面,小程序自带的组件肯定是无法满足所有需求的。那想要还原比较炫酷好看的UI的时候就必不可少需要自定义组件了。写过许多自定义组件了,也遇到过许多坑,这里说一个比较头大的坑,就是引入自定义组建的时候,使用selectComponent获取自定义组件对象时,返回null的问题。

      简单示例

   因为这里我们说的主要是selectComponent返回为null的问题,其他问题先不考虑,这里假设我有一个自定义组件QrCodeDialog,且自定义组件的代码没有问题(组件代码本身的问题就不在本次讨论范围了)。

这个时候我在Main界面引用了QrCodeDialog,却发现this.selectComponent()方法返回的null。

问题排查与分析

  1.那首先最基本的就是看页面的json引用路径是否正确

2.看看wxml文件里面的选择器是否设置选择器,比如我这里设置的是id选择器

(这里提一下自定义组件使用什么名字的标签是由页面的json文件中引用自定义组件时的key决定的,比如我引用的时候key定义的是qrcode_dialog,那么在wxml文件使用的时候组件名就是qrcode_dialog,这个大家应该都知道^_^)

3.看看在页面的js文件里面引用的代码

注意这个selectComponent方法里面的参数要与wxml里面设置的id选择器的值相对应,比如我的用的id选择器就用#号+id

 

如果检查过后上面说的,全都没问题的话,那多半就是wxml中自定义组件的那段代码还没渲染到就使用selectComponent引用了组件,这个时候的返回值肯定是null。产生这种大致就下面两种情况。

1.wx:if属性使用不当。

     为什么说wx:if使用不当会导致selectComponent返回为null呢?这里不得不提一下wx:if与hidden属性的区别,这两个属性我想大家都比较熟悉,都是用来控制显示与隐藏的。要说有什么区别,有些可爱的同学就会脱口而出:“wx:if条件为true就显示,反之则隐藏;hidden条件为true就隐藏,反之则显示!”。嗯,说的没错,这确实是最直观最明显的区别。但是说的并不全!他们还有一个区别,就是如果你用wx:if包裹了一段代码,界面在渲染的时候,当wx:if的条件为false的时候是不会渲染这段代码的,只有wx:if的条件为true才会渲染这段代码;而用hidden包裹的代码无论条件是为true还是false都会渲染它包裹的代码,只不过为true时将这段布局隐藏了而已。

 

    说到这个区别我想有些小可爱已经明白了。假如你的自定义组件包裹在了wx:if下,并且在你使用selectComponent获取组件对象的时候,这个wx:if的条件还为false,也就是说你引用的时候,页面并没有渲染到你的自定义组件,这时候使用selectComponent获取的组件对象当然为空,因为都还没渲染到。

举个简单的例子:

wxml文件

<view wx:if="{
   {a==1}}">
   <qrcode_dialog id="vipQrcode1" />
</view>

qrcode_dialog 是我的自定义组件,使用view包裹,并使用wx:if添加条件如果a==1就显示

js文件添加引用代码

    this.vipQrcode1 = this.selectComponent("#vipQrcode1")
    console.log("第一次---this.vipQrcode1====", this.vipQrcode1)
    this.setData({
      a:1
    })
    this.vipQrcode1 = this.selectComponent("#vipQrcode1")
    console.log("第二次--=this.vipQrcode1====", this.vipQrcode1)

这里我先直接引用一次,打印一次日志,再看看赋值a为1之后再引用打印一次日志,看看效果:

很显然第一次的时候由于不满足a==1的条件,selectComponent返回的是null,当我赋值了a=1时,这时候满足了if条件,我再次引用就不为空了。

我们在将wx:if换成hidden看看有什么区别,只需要改下wxml文件的代码:

<view hidden="{
   {a!=1}}">
  <qrcode_dialog id="vipQrcode1" isShow="{
   {false}}" />
</view>

hidden的条件就是a!=1就隐藏,js还是之前的代码,先直接引用一次,打印一次日志,再赋值a为1之后再引用打印一次日志,我就不贴了,再看看日志

很显然当我换成了hidden之后,无论是否满足条件selectComponent都不为空。

   说到这里,赶紧看看你页面的wxml文件的布局文件,是不是将自定义组件放在了wx:if里面包裹起来了,并且你引用的时候wx:if的条件是不是为false。如果真的是这种情况导致的就将wx:if换成hidden就好了。

2.自定义组件所在层级太深

       这个意思就是说你的自定义组件嵌套在n个view下面,理论上页面渲染的顺序应该是从外往里,如果你的自定义组件嵌套的非常深,而这个时候你在页面还未渲染完成的时候就开始使用selectComponent引用组件,获取到的对象也有可能是会为null,这个情况不会太稳定,有时候渲染的速度不一样,出现偶尔引用成功,偶尔引用失败的情况。当然这种情况极少出现,反正我这辈子没遇见过。哈哈~夸张了一些,反正我是没遇到过这种情况,不过理论上应该是存在这种情况的。如果真的遇到了这种情况,你可以没必要急着一开始就去引用它,你也可以延迟几秒钟再引用,或者在你需要使用自定义组件里的方法时再引用。

 

说了这么多,其实只要记住this.selectComponent()返回为null的情况无外乎就是两种,要么是引用错误,要么就是未找到自定义组件节点,在发现其他情况的话我在补充。

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_36611526/article/details/103719036

智能推荐

计算机网络sequence number,TCP协议中SequenceNumber和Ack Numbe-程序员宅基地

文章浏览阅读1k次。Sequence Numberlzyws7393074532892018-04-25Number Sequenceqq_391789932452017-09-21理解TCP序列号(Sequence Number)和确认号(Acknowledgment Number)hebbely9822017-01-14Number Sequence(规律)l25336363712902017-07-18Numb..._ack num

计算机系统启动项设置密码,电脑开机第一道密码怎么设置 - 卡饭网-程序员宅基地

文章浏览阅读5.9k次。笔记本电脑怎么进CMOS密码巧设置笔记本电脑怎么进CMOS密码巧设置 笔记本电脑为了保护用户的数据安全,往往采用加密的方式,最常见的还是CMOS密码加密技术。为了让你的重要数据更加安全,你可能需要设置不同的密码,这也就要求你记住许多密码。对于笔记本电脑用户来说,真的需要设置一道道密码关卡吗?非也非也! 一、认识与设置笔记本电脑的CMOS密码 笔记本电脑的CMOS密码大致分为超级密码(Supervi..._电脑第一道密码修改

VulnHub靶机-Jangow: 1.0.1_jangow01-程序员宅基地

文章浏览阅读2.5k次,点赞2次,收藏5次。迟到的文章,就当库存发出来吧~_jangow01

spark实战之RDD的cache或persist操作不会触发transformation计算_spark cache和persist不生效-程序员宅基地

文章浏览阅读1.7w次,点赞2次,收藏5次。默认情况下RDD的transformation是lazy形式,实际计算只有在ation时才会进行,而且rdd的计算结果默认都是临时的,用过即丢弃,每个action都会触发整个DAG的从头开始计算,因此在迭代计算时都会想到用cache或persist进结果进行缓存。敝人看到很多资料或书籍有的说是persist或cache会触发transformation真正执行计算,有的说是不会!敝人亲自实验了一把..._spark cache和persist不生效

html文字滚动_html滚动-程序员宅基地

文章浏览阅读2.4k次。HTML之marquee(文字滚动)详解语法:以下是一个最简单的例子:代码如下:Hello, World下面这两个事件经常用到:onMouseOut=“this.start()” :用来设置鼠标移出该区域时继续滚动onMouseOver=“this.stop()”:用来设置鼠标移入该区域时停止滚动代码如下:onMouseOut=“this.start()” :用来设置鼠标移出该区域时继续滚动 onMouseOver=“this.stop()”:用来设置鼠标移入该区域时停止滚动这是一个完_html滚动

leecode++理解_auto row : rows-程序员宅基地

leecode++理解:本文介绍了一些LeetCode题目的解析和思路,包括两数相加、寻找有序数组的中位数、最长字串、整数反转等。还讨论了一些下标规律和正则表达式匹配问题。

随便推点

笔记-Java线程概述_java 线程概述-程序员宅基地

文章浏览阅读629次。Java Concurrency in Practice中对线程安全的定义:当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替运行,并且不需要额外的同步及在调用方代码不必做其他的协调,这个类的行为仍然是正确的,那么这个类就是线程安全的。显然只有资源竞争时才会导致线程不安全,因此无状态对象永远是线程安全的 。过多的同步会产生死锁的问题,死锁属于程序运行的时_java 线程概述

MATLAB从文件读取数据_matlab读取数据-程序员宅基地

文章浏览阅读1.2w次,点赞10次,收藏61次。读取表单Sheet2中部分信息。_matlab读取数据

【实践】基于spark的CF实现及优化_spark cf-程序员宅基地

文章浏览阅读1.4w次。最近项目中用到ItemBased Collaborative Filtering,实践过spark mllib中的ALS,但是因为其中涉及到降维操作,大数据量的计算实在不能恭维。所以自己实践实现基于spark的分布式cf,已经做了部分优化。目测运行效率还不错。以下代码package modelimport org.apache.spark.broadcast.Broadcastimp_spark cf

ijkplayer直播播放器使用经验之谈——卡顿优化和秒开实现_libijkplayer 播放直播流卡顿-程序员宅基地

文章浏览阅读1.8w次。 在我的博客移动平台播放器ijkplayer开源框架分析(以IOS源码为例),大致介绍了一下ijkplayer的基本函数调用顺序和主要线程作用,本博客想介绍一下在直播应用中,针对卡顿和秒开做的一些优化,本优化经验主要是用在Android系统上,ios上也可以借鉴,按本博客修改代码,网络带宽足够的情况下,音视频播放基本流畅不卡顿,首屏时间在500ms以内。 首先来看直播应用中的卡顿。直..._libijkplayer 播放直播流卡顿

数据挖掘实践(金融风控-贷款违约预测)(三):特征工程_金融风控(大数据)特征工程-程序员宅基地

文章浏览阅读2.3k次,点赞3次,收藏28次。数据挖掘实践(金融风控-贷款违约预测)(三):特征工程目录数据挖掘实践(金融风控-贷款违约预测)(三):特征工程1.引言2.特征预处理2.1缺失值填充2.2时间格式处理2.3类别特征处理3.异常值处理3.1 检测异常的方法一:正态分布法3.2 检测异常的方法二:箱型图3.3异常值的处理方法4.数据分桶5.特征交互6.特征编码6.1 labelEncode 直接放入树模型中6.2 逻辑回归等模型要单独增加的特征工程7.特征选择7.1 Filter7.2 Wrapper (Recursive feature _金融风控(大数据)特征工程

关于datagrip与mysql连接时下载驱动失败时的解决方法_datagrip插件下载失败-程序员宅基地

文章浏览阅读1.1k次,点赞7次,收藏11次。2️⃣若失败消息提示需要更换http,去阿里云中找到相关镜像 测试连接通过后重新下载驱动。3️⃣上述方法还是不行 可以关闭data grip后再来几遍。1️⃣首先将电脑连接的Wi-Fi关闭 连接手机热点。_datagrip插件下载失败