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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...