Element: 分页组件和表格组件一起使用时的问题

Created on 14 Feb 2017  ·  25Comments  ·  Source: ElemeFE/element

如题,当我给分页组件上绑定了@current-change事件后,
我原意是想每次点击第1,2,3,4...页时,发起ajax请求,去获取表格的数据
但是现在的问题是当我表格的数据在通过vue - created生命周期获取时,当数据渲染完成之后,也触发了@current-change事件。

还有情况例如我的表格还支持搜索功能,当我目前在第4页的时候,搜索后,自然会去第1页,然后也会触发@current-change事件。
有什么办法可以解决吗?

Most helpful comment

@wenner
今早发现我这样的写法也会有问题……如果在页数为1的情况下进行关键词搜索,赋值page为1的话也不会触发current-change事件,因为它本来就是1……
所以还是得用你写的那种方式,简便的话可以像我这样写成三元表达式……

this.option.page == 1 ? this.getList() : this.option.page = 1

具体的应用场景:带有搜索功能的分页表格组件

//html


//js
search(){
this.option.page == 1 ? this.getList() : this.option.page = 1
},
getList(page) {
//ajax请求
}

所以说分页组件在条件搜索下的表现还是有修改余地的……使用者会被列表的请求触发条件迷惑,因为在页码发生变化的同时就将触发

如果搜索关键词的方法直接调用列表请求:
1.用户在表格第一页就搜索关键词,表现正常
2.用户在翻了几页后搜索关键词,此时会在将page置为1时触发列表请求,本身调用列表请求,多请求了1次

如果搜索关键词的方法单纯将page置为1:
1.用户在表格第一页就搜索关键词,无法触发列表请求
2.用户在翻了几页后搜索关键词,表现正常

建议:
可以给分页组件配置一个option属性
当该属性存在,且发生变化时:
1.由其代替current-page的变化触发current-change事件
2.并且在current-change事件内对current-page的操作不会触发该事件本身

All 25 comments

额,因为确实发生了改变啊

@liril-net 但感觉这样有些不合理啊,那希望可以给 页码1 2 3 4..增加一个点击事件

@radicalviva 你点击页码,,不就是想改变当前页的内容,那和 current-change 事件不就没区别了。

@liril-net 有区别,我绑定的是 click 事件。

@radicalviva 额,我的意思是你click还有别的用途吗?

@liril-net 目前没有额。 我只是增加一个click函数,因为current-change事件既然是监听 页码 变化,那就不能单纯地由 点击 页码 来发生了

@radicalviva 你的意思是,监听页面内部内容是否真正的改变了?

@liril-net 没有啊。。 我有点不清楚你的意思了。 我们回到目前这个问题,你有什么想法吗?我可能需要很多的if else进行hack

@radicalviva 你可以写个 demo 来表达一下,你想要的效果吗?

link
额,不知道为什么,js代码没有运行起来。。。

这个地方我来解释下,currentPage 会在自身不合理的情况下调整自己的值,比如 > total || < 0。

如果不想他自己调整,在没有获取到 total 之前设置 total 为 null,这样 currentPage 就不会认为有 total 的限制,就不会自我调整,这样就不会触发 current-change 事件。

也就是 vue - created 周期的创建 current-change,只要设置 total 绑定的变量的初始值为 null 就可以避免了。

    <div class="page" v-if="user_list">
      <el-pagination
        layout="total, prev, pager, next"
        :total="user_list.total"
        :page-size="user_list.per_page"
        :current-page="Number(user_list.current_page)"
        @current-change="changeCurPage">
      </el-pagination>
    </div>

这是我在页面中的代码,
而这个user_list是通过以下方式获取

  data: {
    community_list: {}, //小区列表
    city_list: [],
    status_list: {},
    user_list: {},
    mobile: '',
    city: '',
    community: '', //小区
    status: '',
    start_time: '',
    end_time: '',
    can_edit_date: false //禁止编辑日期,只能选择日期
  },
  created: function () {
    this.$http.get('/yan/user/user-list/query')
              .then(function (res) {
                if (!res.data.error) {
                  this.community_list = res.data.community_list
                  this.status_list = res.data.status_list
                  this.city_list = res.data.city_list
                  this.user_list = res.data.user_list

                }
              })
              .catch(function (err) {

              })
  },

@furybean 这样看上去我一开始似乎就没有问题啊

@furybean 我测试了下,在user_list还未获取到数据的时候 将它 v-if 置为 true,就可以规避了,而一开始将user_list初始化为{total: null}并不能解决 是我写错什么地方了吗。

@radicalviva 我写个例子测一下

@radicalviva 你的场景有点复杂,我重现不出来。不过我刚才结论的例子见这里:http://jsfiddle.net/L7f9b7g4/6/

@furybean ok,我明白你的意思了。 谢谢。
@liril-net 谢谢。

就这个问题我想问一下 , 情况是:

  1. current-change时候,我会执行ajax请求去读取数据
  2. size-change的时候,我想设置currentPage = 1 ,然后再次发起请求
  3. 搜索的时候 , 比如keyword改变了,然后进行搜索 , 这时候肯定需要把currentPage设置等于1的,因为条件改变了
    只要手动设置currentPage,那么就会触发一次current-change
    所以我想知道
  4. 我这样做是不是有问题 , 是执行流程的问题么...
  5. 如果没问题,那么如何在手动设置currentPage时不触发current-change

代码类似下面:

 data: {
   return {
      condition: {keyword:""} , 
      pageOptions: {currentPage:1 , total:400 , pageSize:100}
   ]
 } , 
methods:{
  //size change handler
  onSizeChange(){
    //设置currentPage = 1 
    this.pageOptions.currentPage = 1;
   //读取数据
    this.loadData();
  } , 
  //currentpage change handler
  onCurrentChange(){
    //直接读取数据
     this.loadData();
  } ,
  //search
  search(){
    //因为是改变条件进行搜索,所以设置页面为第一页
    this.pageOptions.currentPage = 1;
    //读取数据
    this.loadData();
  } ,
  //读取数据
  loadData(){
    //获取要传入的参数
    var condition = _.extend(_.clone(this.condition) , this.pageOptions);
   //AJAX请求
    xxResource.get(condition)
      .then(...)
  }
}

这里只要在size-change , search中设置currentpage , 那么 , 就会触发currentchange

所以我后面都得自己判断一下,感觉有点麻烦 , 类似

onSizeChange(){
  if (this.pageOptions.currentPage == 1){
    //如果当前page已经等于1,则手动loadData
    this.loadData();
  }else{
    //如果当前page不等于1,则改变currentPage,自动触发onCurrentChange
    this.pageOptions.currentPage = 1;
  }
}

对于这个问题我的做法是不给keyword这类的搜索直接绑到ajax请求上……
而是直接在组件内维护一个option对象,在调用请求时直接作为参数传递
option.page与分页的current-page属性直接绑定
在提交搜索的同时调用一个方法给option对象的对应属性重新赋值
那之后,将option.page置为1
让它自动触发current-change就好

@NadokaCiel 能稍微写个代码的例子么...没看太明白

@wenner
今早发现我这样的写法也会有问题……如果在页数为1的情况下进行关键词搜索,赋值page为1的话也不会触发current-change事件,因为它本来就是1……
所以还是得用你写的那种方式,简便的话可以像我这样写成三元表达式……

this.option.page == 1 ? this.getList() : this.option.page = 1

具体的应用场景:带有搜索功能的分页表格组件

//html


//js
search(){
this.option.page == 1 ? this.getList() : this.option.page = 1
},
getList(page) {
//ajax请求
}

所以说分页组件在条件搜索下的表现还是有修改余地的……使用者会被列表的请求触发条件迷惑,因为在页码发生变化的同时就将触发

如果搜索关键词的方法直接调用列表请求:
1.用户在表格第一页就搜索关键词,表现正常
2.用户在翻了几页后搜索关键词,此时会在将page置为1时触发列表请求,本身调用列表请求,多请求了1次

如果搜索关键词的方法单纯将page置为1:
1.用户在表格第一页就搜索关键词,无法触发列表请求
2.用户在翻了几页后搜索关键词,表现正常

建议:
可以给分页组件配置一个option属性
当该属性存在,且发生变化时:
1.由其代替current-page的变化触发current-change事件
2.并且在current-change事件内对current-page的操作不会触发该事件本身

遇到了一样的应用场景,感觉很坑啊,没有更好的办法的话,打算自己写一个pagination。

感觉这个应该设置成了ant-design的table一样,省去这么多麻烦哈。

这里主要问题是数据是双向绑定的,要是可以单向绑定就不会有这些奇奇怪怪的场景

prev-click,next-click 这两个事件触发的之后current-change事件也触发了, 好难受

Was this page helpful?
0 / 5 - 0 ratings