angular2-7中的變化監測

来源:https://www.cnblogs.com/siegaii/archive/2019/04/13/10701384.html
-Advertisement-
Play Games

最近做公司新項目用的angular7,中碰到了一個很頭疼的問題在綁定對象中的數據改變時,頁面視圖沒有跟新,需點擊頁面中的時間元素後才會更新。以前使用angularJs也經常碰到類似情況,這種時候一般的方式使使用臟檢查(Dirty checking)讓angularJs檢查綁定到視圖上的數據來實現對頁 ...


    最近做公司新項目用的angular7,中碰到了一個很頭疼的問題在綁定對象中的數據改變時,頁面視圖沒有跟新,需點擊頁面中的時間元素後才會更新。以前使用angularJs也經常碰到類似情況,這種時候一般的方式使使用臟檢查(Dirty checking)讓angularJs檢查綁定到視圖上的數據來實現對頁面數據的刷新。

  接觸angular7時間還不久,angular高版本中提供了一系列組件的生命周期鉤子,能在組件生命周期的各個階段,對組件進行操作,監測組件中輸入數據的變化,基本少很少碰到需要用到類似於angularJs中臟檢查的情況。一直以為在高版本中的angular中已經不會出現需要臟檢查的情況了,可是該來的遲早會來。

  在項目中由於使用了公司的自己的播放插件,angular自身的事件註冊機制無效,只能使用原生的js位視頻播放插件註冊點擊事件。實現點擊插件後通過插件綁定的回調函數將該分屏信息發送給父組件,在父組件中通過對父組件綁定對象中的屬性值的改變來改變父組件的樣式。 

  

// 插件中的代碼片段
ngAfterViewInit() {
        // 頁面視圖初始化完成之後為視頻播放插件添加點擊事件
        this.videoObj = document.getElementById('obj' + this.screen.id);
        this.videoObj.addEventListener('click', () => {
            this.selectThisScreen(this.screen);
        }, false);
 }

private selectThisScreen(screen) {
        // 輸出該分屏對象,輸出給父組件
        this.screenSelected.emit(screen);
}


// 父組件中的代碼片段
private selectedScreen(screen) {
   this.videoLayoutService.selectedScreen(screen, this.videoLayoutOutput);
}

// videoLayoutService 片段
this.screensConfig.screens.map(item => {
    if (item.id === screen.id) {
        item.selected = !item.selected; // 這是想要更新的值!!
        if (item.selected) {
            videoLayoutOutput.emit({
                device: {
                    id: screen.device.Id,
                    code: screen.device.SerialNo,
                    selectedCamera: screen.device.SelectedCamera
                }
            });
        } else {
            videoLayoutOutput.emit({ device: { id: null, code: null, selectedCamera: null } });
        }
    } else if (item.id !== screen.id) {
        item.selected = false;
    }
});

 

 

  可是由於插件事件綁定只支持原生js的方式,沒有有使用angular自身的事件綁定機制(已測試,在不適用該插件的條件下,使用angular自身的事件綁定機制view層能夠監測到數據的跟新),view層沒能監測到綁定數據的變化。在嘗試了各種方式,和各種生命周期鉤子後(甚至測試了ngDoCheck)都沒有效果後都沒能達到想要的效果,這時我想會不會現在angular7中也存在和angularJs中數據更新視圖沒更新的一樣問題,如果是那也應該有類似與$scope.$applay()這樣類似的方式來解決這個問題。

  然後去查了一下官網文檔,在文檔中沒有直接找到類似方法。後去網上找,後來在篇文章中發現了NgZone這個服務(具體哪一篇忘記記錄了,找的博客太多了後來忘記了),然後去官網查了查用法。

  官網文檔中使這樣描述的:An injectable service for executing work inside or outside of the Angular zone.(用於在Angular區域內外執行工作的可註入服務。)看的雲里霧裡。。然後又看下麵的說明。

  The most common use of this service is to optimize performance when starting a work consisting of one or more asynchronous tasks that don't require UI updates or error handling to be handled by Angular. Such tasks can be kicked off via runOutsideAngular and if needed, these tasks can reenter the Angular zone via run.

  大概是說這個服務最常見的用途是在啟動一個或多個非同步組成工作是優化性能時使用,這些任務不由angular處理UI更新或錯誤處理(感動終於找到問題所在了!因為插件使用原生js進行事件綁定,沒有走angular自身的事件綁定機制導致了angular框架不處理UI更新。。所以需要在這裡使用NgZone這個服務),這些任務可以通過runOutsideAngular啟動,如果需要,這些任務可以通過run重新進入Angular區域。

  也就是說我現在可以使用NgZone服務的提供的run()方法將這個事件加入到angular的UI更新管理區域中,一切引刃而解。

  在父組件中註冊NgZone服務使用run()方法

// 父組件中的代碼片段

constructor(private videoLayoutService: VideoLayoutService, private zone: NgZone) {
}

private selectedScreen(screen) {
  this.zone.run(() => {
      this.videoLayoutService.selectedScreen(screen, this.videoLayoutOutput);
  });
}

 

 

 

  最後來簡單說明下NgZone中的幾個方法的使用

  run():在Angular區域內同步執行fn函數,並返回函數返回的值。通過run運行函數允許您從在Angular區域之外執行的任務(通常通過runOutsideAngular啟動)重新進入Angular區域。在這個函數中調度的任何未來任務或微任務都將在Angular區域中繼續執行。如果發生同步錯誤,它將被重新拋出,而不是通過onError報告。

  runTask():以任務的形式在Angular區域內同步執行fn函數,並返回函數返回的值。通過run運行函數允許您從在Angular區域之外執行的任務(通常通過runOutsideAngular啟動)重新進入Angular區域。在這個函數中調度的任何未來任務或微任務都將在Angular區域中繼續執行。如果發生同步錯誤,它將被重新拋出,而不是通過onError報告。

  runGuarded() :與 run() 相同,除了同步錯誤是通過onError捕獲和轉發的,而不是重新拋出。

  runOutsideAngular() : 在Angular的父區同步執行fn函數,並返回函數返回的值。通過runOutsideAngular運行函數可以讓您逃離Angular的區域,並做一些不會觸發Angular變化檢測或受制於Angular錯誤處理的工作。在這個函數中調度的任何未來任務或微任務都將在Angular區域之外繼續執行。使用run重新進入Angular區域並執行更新應用程式模型的工作。

 

  

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv ...
  • React 與 Vue 之間的對比,是前端的一大熱門話題。 vue 簡易上手的腳手架,以及官方提供必備的基礎組件,比如 vuex , vue router ,對新手真的比較友好; react 則把這些都交給社區去做,雖然這壯大了 react 的生態鏈,但新手要弄出一套趁手的方案挺麻煩的,不過好在現在 ...
  • 一,更換背景: 1.首先需要上傳幾張圖片到自己的博客園相冊中:如圖: 2.然後點擊其中一張單擊右鍵複製圖片地址鏈接 3.切換到博客園設置頁面中(我這裡選擇的是CornflowerBlue這個皮膚): 4.複製下麵代碼到“頁面定製CSS”中: 5.找到這一段代碼: 將url更改為剛纔複製的圖片鏈接; ...
  • 設置 JavaScript 對象屬性為事件處理程式: 1、註冊事件處理程式的最簡單方法就是通過設置事件目標的屬性為所需事件處理程式函數 2、這種事件處理程式註冊技術適用於所有瀏覽器的所有常用事件類型 3、事件處理程式屬性的缺點是其設計都圍繞著假設每個事件目標對於每種事件類型將最多只有一個處理程式 註 ...
  • # apt-get update # apt-get install -y python-software-properties software-properties-common # add-apt-repository ppa:chris-lea/node.js # apt-get updat ...
  • 1.安裝Node封裝模塊 安裝Node封裝模塊很重要,因為開發項目中會用到各種各樣的功能,這時就需要去下載開源的模塊 使用npm install <module_name> module_name為模塊名稱,命令下Node模板到你的開發環境中,並將其放置在node_modules文件夾中, 例如下載 ...
  • (function ($) { $.getUrlParam = function (name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).mat ...
  • 1.Node.js中文官網http://nodejs.cn/download/下載node.js 學習node.js需要有javascript基礎,沒有基礎的可以在http://www.w3school.com.cn/js/index.asp上學習 下載好後,直接安裝。 2.開發工具 我使用的是ec ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...