簡體   English   中英

在 Angular 加載完所有視圖后運行 Javascript

[英]Run Javascript AFTER Angular Has Finished Loading All Views

我正在使用 Angular 構建一個 Web 應用程序,我試圖找到一種方法來等待所有data-ng-include元素都已評估並且包含完成加載。 例如,菜單是一個加載的視圖,每個頁面的主要內容也是如此,因此至少有兩個data-ng-include被評估和加載。 最重要的是,菜單 include 嵌套了data-ng-repeat來構建我的菜單。 我需要一種在所有這些包含和其中的任何角度函數都已加載並且 DOM 實際准備就緒后啟動腳本的方法。

當 Angular 完成頁面設置時,是否有任何事件被觸發?

AnguarJS 的實現是基本的,我們基本上通過使用 data-ng-include 將其用於模板化。 每個頁面都是一個視圖(不是角度視圖,只是一個 html 文件),通過 data-ng-include 加載,頁眉和頁腳在其上方和下方。 標頭還動態加載包含 angular.html 的全局視圖(同樣不是角度視圖)html 文件。

到目前為止,除了模板之外,菜單是唯一使用 AngularJS 的東西。 它使用它使用 JSP 動態生成並插入到從服務器返回的 DOM 中的 JSON 對象來創建菜單。

為了讓前端人員的工作更輕松,任何類型的重復 JavaScript 功能都被編碼到模塊中,這些模塊在頁面加載時被檢測到,並使用需要附加 JavaScript 功能的元素上的 data-features 屬性動態加載到。

例如,您可能有<div id="mySubMenu" data-features="subMenu"></div> 在頁面加載時,會檢測每個帶有 data-features 元素的元素,並加載關聯的 JS 模塊,在這種情況下,我們將加載/scripts/modules/subMenu.js

我需要的是一種延遲運行此功能檢測和附件的方法,直到包含或其他角度函數產生的所有元素都在頁面上並准備好進行操作,特別是因為其中可能存在具有數據特征屬性的元素包括。

其他地方有人提到在身體上放一個控制器,但什么都不放:

$scope.$on('$viewContentLoaded', function() {
    // Init Features Here
});

那沒有用,所以我在這里尋找其他選擇。

我最終在這個問題中使用了 Theo 的解決方案: 當 angular.js 完成加載時發送事件

在加載的內容上:

$rootScope.$on('$includeContentLoaded', function() {
    //do your will
});

關於請求的內容:

$rootScope.$on('$includeContentRequested', function() {
    //...
});

我確信這不是正確的方法,但是......

將下面的函數放在我的視圖控制器中,在視圖加載到我的應用程序中后運行該函數。 我相信該函數會在視圖加載后的下一個摘要循環中運行(如果錯誤,請在此處糾正我),因此它會在頁面形成后運行。

setTimeout(function(){
  //do this after view has loaded :)
  console.log('success!');
}, 0);

在每個視圖 setTimeouts 返回后,您可以通過回調將它們鏈接在一起和/或使用異步並行庫來執行另一個函數。

我認為合適的答案是否定的。 您必須改變查看應用程序和模型的方式,並使其適應“角度方式”。 很可能有一種更健康的方式來實現您的需求。 如果您需要將事件附加到元素,您可能想要使用指令,但當然我沒有足夠的信息在這個階段判斷什么是最好的。

angular.module 和指令是一個很好的探索選擇。

這是一個關於如何將兩者與 JQUERY 插件一起使用的 plunker 演示:

http://plnkr.co/edit/WGdNEM?p=preview

這是一個在單獨文件上帶有指令的示例:

http://plnkr.co/edit/YNBSWPLeWqsfGvOTwsMB?p=preview

您可以使用 JQuery Promise,並在您的 Angular 根控制器中實現此承諾。 在 angular 控制器或 jquery 代碼運行之前設置承諾:

var AppReadyDeferred = $.Deferred();
var AppReadyPromise = AppReadyDeferred.promise();

一旦一切准備就緒,在你的角度控制器里面,做

AppReadyDeferred.resolve();

在你的 jQuery 代碼中等待它被解決

window.AppReadyPromise.done(() => {
  // Angular is ready to go!;
});

使用 ng-cloak 在編譯之前延遲顯示模板。 您還可以向具有 ng-cloak 的 html 元素添加一個隱藏字段作為最后一個子元素(最好在 body 標簽或 ng-app 開始的任何地方使用它),然后您可以檢查此隱藏元素是否存在間隔循環

您的隱藏字段部分將是這樣的

<div ng-include="'ngtplhidden'"></hidden>
<script type="text/ng-template" id="ngtplhidden">
<span id="elemidToCheckInAnIntervalFunc"></span>
</script>

您可以嘗試使用document.onreadystatechange

document.onreadystatechange = x => {
    console.log('ready!');
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM