上一篇說到如何在前端作多張圖片的拖動排序,這篇將會從數據庫表的角度,看如何記錄這些圖片的順序。javascript
首先想到的是在數據庫photo表
中添加字段order
,用來記錄圖片在其所在的相冊中的位置.表的結果相似於
album_id是圖片所在相冊的idhtml
用戶上傳圖片時,選出相冊最大的order,前端
select max(order) from photo where album_id=?
而後在插入行的時候,order列是max(order)+1.java
圖片移動到其餘相冊時,修改album_id爲目標相冊album_id,而後像上面,選出目標相冊最大的order,並將其設置爲要移動的圖片order.程序員
多張圖片拖動排序時,。。。本屌不敢想象,太複雜了。sql
和上面添加order
字段相似,這裏添加字段update_time
,表示圖片最近一次更新的時間。數據庫
上傳圖片,update_time
是上傳時間。segmentfault
移動圖片,update_time
是移動操做當前的時間。ui
圖片拖動排序,好比
圖片移動到圖片2,3之間,這時,將被移動圖片的update_time
設置爲圖片2,3的update_time之和除以2
,以確保順序。
若是拖動的是多張圖片,好比拖動2張,那第2張圖片的update_time
是上圖中第3(第一張拖動圖片)
,4張圖片的update_time之和除以2
.其餘的依次類推。spa
qq空間裏圖片的批量管理,也有拖動排序。看下傳遞給後臺的參數
codeList
是選中拖動圖片的photo_id,以_
做爲分隔符,這裏選中了3張圖片。prevKey
,nextKey
是拖動的目標位置左右兩邊圖片的photo_id.prevIdx
,nextIdx
是拖動的目標位置左右兩邊圖片的索引,這裏是想把圖片插到第2,3張圖片之間。
看到上面的參數,是否是很容易想到雙向鏈表
?
上圖是相冊沒有進行過任何拖動排序的狀況,prev
,next
字段爲0分別表示該圖片已經相冊是第一張或最後一張圖片。
如今拖動排序,圖片從左到右的photo_id
依次爲1-8,拖動的圖片photo_id
是7,目標是photo_id
是2,3的圖片之間。
具體操做
選出拖動圖片的prev
,next
select prev,next from photo where photo_id=7
選出拖動圖片的前一張(若是有)圖片和後一張(若是有)圖片
select photo_id as prev_photo from photo where photo_id<7 limit 1 select photo_id as next_photo from photo where photo_id>7 limit 1
將拖動圖片的前一張圖片和後一張圖片連起來
update photo set next=next_photo where photo_id=prev_photo update photo set prev=prev_photo where photo_id=next_photo
將拖動圖片插到目標位置
update photo set next=7 where photo_id=2 update photo set prev=7 where photo_id=3 update photo set prev=2,next=3 where photo_id=7
這裏只拖動了一張圖片,若是拖動多張的話,代碼就要複雜些,由於拖動的各照片要構建雙向鏈表
。本屌暫時不寫多張拖動的狀況,之後有時間的話會補上。
找到最後一張圖片
select photo_id as last_photo from photo where next=0
上傳圖片
上傳的圖片放到最後
update photo set next=upload_photo where photo_id=last_photo update photo set prev=last_photo,next=0 where photo_id=upload_photo
選出拖動圖片的prev
,next
select prev as prev_photo,next as next_photo from photo where photo_id=7
將刪除圖片的前一張圖片和後一張圖片連起來
update photo set next=next_photo where photo_id=prev_photo update photo set prev=prev_photo where photo_id=next_photo
刪除圖片
前面的操做都是在一個相冊中進行,因此where條件中就沒寫album_id.
qq空間中圖片移動到另外一個相冊,圖片會被排到相冊的最後一個位置,這裏也同樣。
具體的
選出移動圖片的prev
,next
select prev,next from photo where photo_id=move_photo
選出移動圖片的前一張(若是有)圖片和後一張(若是有)圖片
select photo_id as prev_photo from photo where photo_id<move_photo limit 1 select photo_id as next_photo from photo where photo_id>move_photo limit 1
將移動圖片的前一張圖片和後一張圖片連起來
update photo set next=next_photo where photo_id=prev_photo update photo set prev=prev_photo where photo_id=next_photo
找到另外一個相冊中的最後一張圖片
select photo_id as last_photo from photo where next=0 and album_id=another_album
移動的圖片放到最後
update photo set next=move_photo where photo_id=last_photo
設置移動圖片的prev
,next
update photo set prev=last_photo,next=0 where photo_id=move_photo
雙向鏈表
如何呈現?上一節說的是在不一樣場景下,數據庫表該如何變化,實際就是很簡單的雙向鏈表
操做。可是若是用這種表結構不能按用戶自定義的順序把圖片呈現出來,仍是沒什麼卵用。
下面說說怎麼呈現。
一般圖片都是按時間降序排列,這裏簡單的用order by photo_id desc
表示.而自定義的順序
不能簡單的經過對prev
,next
列的排序得到。
var data=[//順序:5 2 3 9 8 1 4 10 7 6 {id:10,prev:4,next:7}, {id:9,prev:3,next:8}, {id:8,prev:9,next:1}, {id:7,prev:10,next:6}, {id:6,prev:7,next:0}, {id:5,prev:0,next:2}, {id:4,prev:1,next:10}, {id:3,prev:2,next:9}, {id:2,prev:5,next:3}, {id:1,prev:8,next:4} ];
既然數據庫不能排序就只有寫代碼排序了。這裏用js排序,代碼很簡單,沒幾行
順序:5 2 3 9 8 1 4 10 7 6 <div ms-controller='sort'> <ul> <li ms-repeat='list'> pic{{el.id}} prev:{{el.prev}} next:{{el.next}} </li> </ul> </div>
require(['avalon'],function(avalon){ var sort=avalon.define({ $id:'sort', list:[] }); avalon.scan(); var data=[//先按時間降序排列,而後自定義順序:5 2 3 9 8 1 4 10 7 6 {id:10,prev:4,next:7}, {id:9,prev:3,next:8}, {id:8,prev:9,next:1}, {id:7,prev:10,next:6}, {id:6,prev:7,next:0}, {id:5,prev:0,next:2}, {id:4,prev:1,next:10}, {id:3,prev:2,next:9}, {id:2,prev:5,next:3}, {id:1,prev:8,next:4} ]; var next=0,result=[],photo_id_arr=[];//photo_id_arr保存全部的photo_id data.sort(function(a,b){//排序只是爲了保證data[0]取到的是鏈表的頭元素 return a.prev-b.prev; }); avalon.each(data,function(i,el){ photo_id_arr.push(el.id); }); while(next!=-1){//若是元素的next(即下一個photo_id)在photo_id_arr中存在 var cur=data[next]; result.push(cur); next=photo_id_arr.indexOf(cur.next); } sort.list=result; });
例子下載
本屌非開發qq空間相冊的程序員,以上純屬猜想。若有雷同,純屬巧合