Angularjs的最主要的一個應用場景就是單頁面應用(SinglePageApplication),但是SPA中會有一個明顯的問題,在視圖切換的時候,它只會用新視圖去替換視圖容器內的HTML,但如果舊視圖在加載之后動態生成一些DOM元素,而這些新生成的DOM元素並沒有在容器內的話,那么視圖切換后,這些DOM元素還會存在。因為angular的視圖切換是由js來動態完成的,並沒有讓瀏覽器去重新加載整個頁面。
下面就是一個例子:
總共有兩個頁面,使用ngRoute來路由。視圖容器如下:
其中一個頁面是使用xheditor來創建的編輯器,它的工具欄能浮動出一些小框,其實就是動態在body末尾生成一些DOM元素,如下圖:
最下面紅色框就是新生成的元素,如果我們現在切換回首頁視圖會怎么樣?
這些元素還在的,因此我們需要在離開這個視圖的時候清除掉這些DOM元素,那么視圖加載到離開都有些什么事件呢?
從官方文檔看,ngView只有一個事件$viewContentLoaded
,名字是在視圖加載完后執行的內容。因此我們來測試如下的代碼:
在視圖層添加如下代碼:
在控制器中添加如下的代碼:
看下運行的效果:
視圖層中的代碼率先被執行,然后進入到控制器的邏輯,最后觸發$viewContentLoaded。
從上面的代碼看,如果我們加載后的事件只需要對DOM進行操作,那么在視圖層的script中即可,但是如果需要使用到控制器中的數據的話,就必須在控制器中完成。
進入視圖的事件搞定了,那么離開的事件呢?官方文檔沒有介紹,但是其他文檔中我們發現$location和$route有change相關的事件。
代碼如下,為了更早的生效,這段代碼可以寫入到app.js中:
運行結果如下:
我們完全可以在$locationChangeSuccess中判斷fromUrl是不是當前視圖的hash,如果是然后執行離開視圖的操作即可。
同理的事件還有$routeChangeStart和$routeChangeSuccess,其實官方文檔中可以看到$route是依賴於$location的,因此我們可以猜測其實他們應該是同一個東西,不同的封裝而已罷了。
看如下的代碼:
運行結果:
運行結果中需要注意:$routeChangeSuccess事件是在整個新的視圖加載完成之后才會執行的。
因此要選擇當前視圖離開事件的時候,請考慮$locationChangeStart,$locationChangeSuccess,$routeChangeStart。
TIPS:這樣的離開事件可以在進入視圖的時候增加監聽,在離開時執行完相應的操作后,取消監聽,如下:
搞定了,哈哈。學習交流為主。
最后是本文中使用到的代碼:點擊下載 angular1.rar