求助,用angularJs實現下圖功能?


嗯,這個功能很典型,但看上去複雜,實際上很簡單。我給你說下思路吧,你自己寫。

我們要寫好Angular代碼,最關鍵的是要能根據業務,抽象出數據模型來。從這個界面來看,數據模型就是兩個數組(其實是三個)。哪兩個呢,左邊一個,右邊一個啦,但再想想,其實是不夠的,因為有這個搜索功能,所以我們還需要另外一個數組用於存放左側全量的未選元素,這樣,數據模型就有了:

- 剩餘的所有元素數組a

- 經過搜索條件過濾的剩餘元素數組b //這個綁定到左邊的列表

- 已選元素數組c //這個綁定到右邊的列表

然後,很簡單了有沒有,數組b由數組a和搜索條件過濾得出,然後,當選擇b中某個元素的時候,將其從a和b中移除,添加到c中去,反之類似。

然後這部分邏輯寫完,就剩下根據兩個數組生成列表界面的事情了,簡單吧


不錯的場景,從 @徐飛 的答案上講一下:

1. 可以考慮把數組 C 去掉,左右兩個列表都展示搜索(過濾)出來的數組 B。左側展示 B 中全部項目,右側展示 B 中被選中的項目。

2. 甚至可以考慮把數組 B 也去掉,只有一個數組 A(當然,要看具體的場景是否合適)。左側在搜索內容為空時,展示 A 中的所有項目(也就是所有項目都能匹配搜索條件);在搜索內容不為空時,展示 A 中匹配的項目;右側展示的內容參考 1。


angular寫了幾天,剛好回答一下,不怎麼熟悉,有錯誤請指正~

@徐飛 已經說得很明白了,我補充一下數據處理這裡的一點小建議。

所有的MVVM框架都在做一個共同的事情:維護數據,不維護view。

所以任何業務都需要想辦法把業務抽離出一個model來。

但是如果所有的東西都抽離成model的話,model就會變得臃腫。所以可以借鑒react的思路:和業務相關的數據抽離成props(model),和UI相關的抽離成state。

萬萬不要將所有的數據都寫在$scope上,業務一大就好看了。。。

例外就是不應該改變原有數據,在此處可以建立一個state.checkedMap來緩存每一條數據的是否選中狀態。如果只維護數組的話,難免要在原有數據上添加一個不必要的狀態值,這從邏輯上說是不合理的。


@徐飛 徐飛老師補充了思路,我再補充點實現細節,如果按照ng的推薦的思維來寫,這裡應該是要用directive來操作這部分的DOM,換做這裡是後端的form表單這裡會非常容易解決

這裡給個解決這個問題的思路吧,就說幾個點其他就自己實現吧~

既然是ng的那圖中的表單估計也是ng-repeat生成的,這裡要拿到選中那個tr項就要用到這個$event,這裡等同於寫原生js時候的choose(this)

&

拿到這個選中項之後,你有兩種方法操作這個地方第一種可以交給directive(),第二種就是在controler裡面直接用jqlite或者原生來操作這個DOM讓它刪除(這種不符合ng的規範)

angular.module("app").controller("...Ctrl", ["$rootScope", "$scope".....) {
....
$scope.choose(a){
a.target.lastElementChild.style....
}//雖然不推薦但適合新人

最後我建議批量刪除應該是後台介面返回給你的數據再展示出來的,這部分數據邏輯不應該出現在前端,簡單來講就是後台給什麼view什麼,所以那個刪除功能應該是http拿回來數據,再展現出來,而不是view層操作dom來展現~喵


@徐飛 飛哥說的很清晰。

作為使用MV*的前端程序員,首先要做的轉變就是思維方式從畫面驅動轉為數據驅動。

這一點非常重要,按照慣例,說三遍:從畫面驅動轉為數據驅動!從畫面驅動轉為數據驅動!從畫面驅動轉為數據驅動!

當你面對任何需求的時候,大腦中第一反應應該是去抽象和構思整個項目的數據流是如何走的。你該如何構建符合業務需求的數據抽象。

不考慮畫面,把題主的需求抽象一下:

業務的需求是:1個表格對list元素展示、篩選和打標記。另外一個表格只顯示打過標記的內容。

那麼此時需要的數據結構只有1個數組: list。可以對list的元素打標記:checked。

現在再去看頁面,你會發現你完全不需要對左右表格的數據同步花費額外的精力,只需要保證它們是用的是同一份list數據。左側table可以對list進行篩選、修改元素的checked值。右側table負責顯示checked為true的內容。

實現這些需求,angular的filter過濾器、ng-click、ng-show標籤已經完全足夠了

有可能稍微複雜一點的地方是,題主沒有說左右兩個table是不是在一個controller中的。

如果是的話,那list可以放在controller的scope中,天生就是唯一的一份,左右table可以立即使用。

如果不是的話,會稍微麻煩一點。需要用service來保證左右兩個table各自的controller中拿到的是同一個list


用vue實現了一下,可供參考。JS Bin - Collaborative JavaScript Debugging


@徐飛,飛哥說的很清晰,

ng,寫的不多,我就扯一下自己的想法。

按照題主描述的,就是一個數據模型對應多個視圖,那麼可以把左側的數據全部放在一起,並且,為每一項打一個狀態(是否選中)的標籤。右側的視圖完全根據狀態來更新。

這樣做的理由,題干中看到的視圖,數據來源是統一的,並且通過數據各個狀態就可以看出。

當然,數據怎麼分離還是要看業務,記住,是用就數據驅動視圖就可以了。


推薦閱讀:

有了 Angular 之類的 MVC/MVVM 框架是不是可以不學 DOM 了?或者只需簡單了解一下 DOM?
Angular js 初學者該看什麼書啊? ?
如何評價 Angular 2 發布 Beta 版本?
如何看2015年1月Peter-Paul Koch對Angular的看法?

TAG:前端開發 | JavaScript | AngularJS |