weex如何通过this.$el()来获取标签中的动态ID?

我的text是遍历数组得到的,而且每个text都有自己独立的id

<div repeat="{{item in productInfo}}">
 <text class="font-24" rownumber="{{item.goods_id}}" id="{{item.goods_id}}" onclick="changeBgc"></text>
</div>

我想做个选中当前目标改变背景色的动画,但是官方文档里面animation的demo给<text>标签绑定的是写死的Id,例如下面这样:

var testEl = this.$el('test')

我尝试在方法changeBgc里面传入id但是没有效果

<text ...   onclick="changeBgc(item.goods_id)"></text>


//下面这个是方法1---------------------
changeBgc = function(id){
    var productId = id
    var colorEl = this.$el(productId);
    animation.transition(colorEl,{
        styles:{
            backgroundColor: '#000',
            color:'#fff'
        }
    });
}
但是这样会报错
relevance.we:464 Uncaught TypeError: Cannot read property 'goods_id' of undefined

琢磨了半天,换了个思路,代码如下:

//这个是方法二--------------------我可以通过rownumber来获取动态的ID
<text class="font-24" rownumber="{{item.goods_id}}" id="{{item.goods_id}}" onclick="changeBgc"></text>

changeBgc = function(e){
    var productId = e.target.attr.rownumber
    var targetEl= this.$el(productId);  //后来尝试用var target=productId 也是无效
    animation.transition(targetEl,{
        styles:{
            backgroundColor: '#000',
            color:'#fff'
        }
    });
}

打印结果表明,当前目标的ID可以获取,但是依旧无法执行动画,var colorEl=this.$el(productId)里的productId用上述的方法还是传不进去
报错结果——> Cannot read property 'goods_id' of undefined

项目版本是weex1的 不是2.0+的,有哪位大神可以指导一下吗?

-----------------2017年9月14日09:58:43更新
实际测试,第二种方法是有效的。由于本人失误,在问题提出时方法二有些错误的地方,现在已经更正,问题已经解决大家可以参考第二种方法。感谢1L——zwwill的解答

需要注意的是第二种方法 text标签里的id="{{item.goods_id}}"属性不可以省略,不然动画执行不了


补充问题:
现在点击当前目标可以更换颜色,但是切换目标后其他的text颜色不知道怎么控制。。有人做过类似的功能吗?

clipboard.png


问题已解决,详情见1L——zwwill的解答

阅读 4.8k
1 个回答

执行环境的问题,第一种方法在执行的时候item已然不在了,item只在weex解析成virtual-dom的时候存在,并不会像vue那样闭包一个执行环境,所以建议使用vue2.0的写法,
另外,你的第二种写法是对的没有问题

changeBgc = function(e){
    var productId = e.target.attr.rownumber;
    animation.transition(this.$el(productId),{
        styles:{
            backgroundColor: '#000',
            color:'#fff'
        }
    });
}

补充答案:
将之前点击的块的颜色还原,可以在data里设置一个目前选中的标记id,每次新点击时坚持是否有前置色块,如果有就还原颜色。

<text defaultBGC="#fff" defaultFC="#000"></text>
changeBgc = function(e){
    if(!!this.currentId){
        var _tempEl=this.$el(this.currentId);
        animation.transition(_tempEl,{
            styles:{
                backgroundColor: _tempEl.attr.defaultBGC,
                color: _tempEl.attr.defaultFC
            }
        });
    }
    var productId = e.target.attr.rownumber;
    animation.transition(this.$el(productId),{
        styles:{
            backgroundColor: '#000',
            color:'#fff'
        }
    },()=>{this.currentId = productId});
}

此方法的好处是比较通用,可以针对不同的初始背景色做对应的颜色还原,
如果你的选中和非选中状态都是相对统一的,可以简化以上代码。
如果容错度做高的话,就是用遍历的方法把。简要代码如下。

module.exports = {
    date: {
      hasChangedIds: []
    },
    changeBgc(e){
        this.reset();
        var productId = e.target.attr.rownumber;
        animation.transition(this.$el(productId),{
            styles:{
                backgroundColor: '#000',
                color:'#fff'
            }
        },()=>{this.hasChangedIds.push(productId)});
    },
    reset(){
        if(this.hasChangedIds.length>0){
          for(_id in this.hasChangedIds){
            animation.transition(this.$el(_id),{
                styles:{
                    backgroundColor: '#000',
                    color:'#fff'
                }
            });
          }
        }
    }
  }

方法总比困难多。加油

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进