डॉक्यूमेंट तैयार होने पर AngularJS कंट्रोलर में फ़ंक्शन कैसे चलाएं?


254

मेरे पास मेरे कोणीय नियंत्रक के भीतर एक फ़ंक्शन है, मैं चाहूंगा कि यह फ़ंक्शन तैयार दस्तावेज़ पर चलाया जाए, लेकिन मैंने देखा कि कोणीय इसे डोम के रूप में चलाता है।

 function myController($scope)
 {
     $scope.init = function()
     {
        // I'd like to run this on document ready
     }

     $scope.init(); // doesn't work, loads my init before the page has completely loaded
 }

किसी को पता है कि मैं इस बारे में कैसे जा सकता हूं?

जवाबों:


449

angular.element(document).ready()दस्तावेज़ तैयार होने पर हम कॉलबैक संलग्न करने के लिए विधि का उपयोग कर सकते हैं । हम बस नियंत्रक में कॉलबैक संलग्न कर सकते हैं जैसे:

angular.module('MyApp', [])

.controller('MyCtrl', [function() {
    angular.element(document).ready(function () {
        document.getElementById('msg').innerHTML = 'Hello';
    });
}]);

http://jsfiddle.net/jgentes/stwyvq38/1/


64
या आप $ document.ready (फ़ंक्शन () {...}), कोणीय डॉक्स: docs.angularjs.org/api/ng/service/$document
StuR

29
$documentइसका उपयोग करने के लिए आपको इंजेक्शन लगाने की आवश्यकता होगी । angular.elementबाहर काम करता है।
nshew

17
इसका उपयोग करने के लिए आपको $ डॉक्युमेंट को इंजेक्ट करना होगा, लेकिन डॉक्यूमेंट एलिमेंट को संदर्भित करने के लिए यह अनुशंसित तरीका है। आपके पास नहीं है, लेकिन यह परीक्षण के रास्ते को आसान बनाता है।
जेसन कॉक्स

10
documentएक वैश्विक चर है जहां $documentकोणीय द्वारा इंजेक्ट किया जा सकता है और इस प्रकार यह परीक्षण को आसान बनाता है। सामान्य तौर पर यूनिट परीक्षण अनुप्रयोगों के लिए कठिन है जो वैश्विक जेएस चर जैसे दस्तावेज़ या विंडो तक पहुंचते हैं। मुझे यह भी लगता है कि module.runयह कोड कंट्रोलर के बजाय डालने के लिए एक अच्छी जगह है।
14

7
यह मेरे लिए काम नहीं करता है, getElementById कॉल रिटर्न शून्य है।
thePartyTurtle 18

29

इस पोस्ट को देखें पृष्ठ लोड पर कोणीय नियंत्रक फ़ंक्शन को कैसे निष्पादित किया जाए?
तेजी से देखने के लिए:

// register controller in html
<div data-ng-controller="myCtrl" data-ng-init="init()"></div>

// in controller
$scope.init = function () {
    // check if there is query in url
    // and fire search in case its value is not empty
};

इस तरह, आपको दस्तावेज़ तैयार होने तक प्रतीक्षा करने की आवश्यकता नहीं है।


1
अगर मुझे पेज-लोड के बाद कॉल करने की आवश्यकता हो तो क्या होगा?
ऋषि

22

कोणीय स्वचालित रूप से आरंभ करता है DOMContentLoaded घटना या जब कोणीय.जेएस स्क्रिप्ट का मूल्यांकन किया जाता है, तो उस समय दस्तावेज़ का मूल्यांकन किया जाता है। पहले से ही 'पूर्ण' पर सेट है। इस बिंदु पर कोणीय एनजी ऐप निर्देश के लिए दिखता है जो आपके एप्लिकेशन रूट को नामित करता है।

https://docs.angularjs.org/guide/bootstrap

इसका मतलब है कि DOM तैयार होने के बाद कंट्रोलर कोड चलेगा।

इस प्रकार यह सिर्फ है $scope.init()


9
मैंने ऐसा करने की कोशिश की, लेकिन अजीब तरह से यह काम नहीं किया मेरे पेज में कुछ चीजें भरी हुई नहीं थीं
foreyez

और यह कैसे पता चलेगा कि एनोटोमेटेड वेब टेस्ट लिखते समय कोणीय कोड जैसे बटन आदि पर क्लिक करने से पहले यह तैयार है?
अकोस्टैडिनोव

DOMContentLoadedजब दस्तावेज़ को पूरी तरह से लोड और पार्स किया गया है, तब भी निकाल दिया जाता है, लोडिंग खत्म करने के लिए स्टाइलशीट, चित्र और सबफ़्रेमियों की प्रतीक्षा किए बिना। अधिक जानकारी के लिए, देखें कि DOMContentLoaded और लोड घटनाओं में क्या अंतर है?
georgeawg

22

कोणीय कार्यों को शुरू करने के लिए कई समय बिंदु हैं। यदि आप jQuery की तरह कुछ के लिए चाहते हैं

$(document).ready();

आप कोणीय में यह एनालॉग बहुत उपयोगी हो सकता है:

$scope.$watch('$viewContentLoaded', function(){
    //do something
});

जब आप DOM तत्वों में हेरफेर करना चाहते हैं तो यह मददगार होता है। सभी ते तत्वों को लोड करने के बाद ही इसे निष्पादित करना शुरू होगा।

UPD: ऊपर बताया गया है कि जब आप css प्रॉपर्टीज को बदलना चाहते हैं तो वह काम करता है। हालांकि, कभी-कभी यह काम नहीं करता है जब आप तत्व गुणों को मापना चाहते हैं, जैसे कि चौड़ाई, ऊँचाई, आदि। इस मामले में आप निम्नलिखित प्रयास करना चाह सकते हैं:

$scope.$watch('$viewContentLoaded', 
    function() { 
        $timeout(function() {
            //do something
        },0);    
});

यह सुझाए गए उत्तर की तुलना में अधिक योग्य है। मुझे $ टाइमआउट का उपयोग किए बिना यह काम मिला है।
रिची 86

यह मेरे लिए केवल सेटटाइमआउट के साथ काम करता है (0) - इसके बिना उदाहरण के लिए एनजी-रिपीट के तहत सामग्री इस बिंदु पर अभी तक भरी हुई नहीं है
इग्नासियो वाज़क्वेज़

2

मेरे पास एक ऐसी ही स्थिति थी जहां मुझे एक लोड होने के बाद नियंत्रक फ़ंक्शन को निष्पादित करने की आवश्यकता थी और यह भी कि दृश्य के भीतर एक विशेष 3-पार्टी घटक के बाद लोड किया गया था, प्रारंभ किया गया था, और $ गुंजाइश पर खुद के लिए एक संदर्भ रखा था। मेरे लिए काम करना समाप्त हो गया, इस स्कोप प्रॉपर्टी पर नजर रखना और इसके आरंभ होने के बाद ही अपने फंक्शन को फायर करना था।

// $scope.myGrid property will be created by the grid itself
// The grid will have a loadedRows property once initialized

$scope.$watch('myGrid', function(newValue, oldValue) {
    if (newValue && newValue.loadedRows && !oldValue) {
        initializeAllTheGridThings();
    }
});

द्रष्टा को अपरिभाषित मूल्यों के साथ कई बार कहा जाता है। फिर जब ग्रिड बनाया जाता है और अपेक्षित संपत्ति होती है, तो आरंभीकरण फ़ंक्शन को सुरक्षित रूप से कहा जा सकता है। पहली बार देखने वाले को गैर-अपरिभाषित न्यूवैल्यू के साथ बुलाया जाता है, ओल्डवैल्यू अभी भी अपरिभाषित होगा।


1

यहां कॉफ़ीस्क्रिप्ट का उपयोग करके बाहरी नियंत्रक के अंदर मेरा प्रयास है। यह अच्छी तरह से काम करता है। कृपया ध्यान दें कि settings.screen.xs | sm | md | lg स्थिर मूल्य हैं जो एक गैर-कुरूपित फ़ाइल में परिभाषित हैं, जिन्हें मैं ऐप के साथ शामिल करता हूं। मान मीडिया नाम क्वेरी आकार के बूटस्ट्रैप 3 आधिकारिक ब्रेकपॉइंट्स के अनुसार हैं:

xs = settings.screen.xs // 480
sm = settings.screen.sm // 768
md = settings.screen.md // 992
lg = settings.screen.lg // 1200

doMediaQuery = () ->

    w = angular.element($window).width()

    $scope.xs = w < sm
    $scope.sm = w >= sm and w < md
    $scope.md = w >= md and w < lg
    $scope.lg = w >= lg
    $scope.media =  if $scope.xs 
                        "xs" 
                    else if $scope.sm
                        "sm"
                    else if $scope.md 
                        "md"
                    else 
                        "lg"

$document.ready () -> doMediaQuery()
angular.element($window).bind 'resize', () -> doMediaQuery()

1

उत्तर

$scope.$watch('$viewContentLoaded', 
    function() { 
        $timeout(function() {
            //do something
        },0);    
});

केवल वही है जो मेरे द्वारा परीक्षण किए गए अधिकांश परिदृश्यों में काम करता है। 4 घटकों के साथ एक नमूना पृष्ठ में, जो सभी टेम्पलेट से HTML का निर्माण करते हैं, घटनाओं का क्रम था

$document ready
$onInit
$postLink
(and these 3 were repeated 3 more times in the same order for the other 3 components)
$viewContentLoaded (repeated 3 more times)
$timeout execution (repeated 3 more times)

इसलिए ज्यादातर मामलों में एक $ document.ready () बेकार है क्योंकि कोणीय में DOM का निर्माण किया जा सकता है जो कहीं भी तैयार नहीं है।

लेकिन अधिक दिलचस्प, $ viewContentLoaded को निकाल दिए जाने के बाद भी, ब्याज का तत्व अभी भी नहीं मिला।

$ टाइमआउट निष्पादित होने के बाद ही यह पाया गया था। ध्यान दें कि भले ही $ टाइमआउट 0 का मान था, लगभग 200 मिलीसेकंड निष्पादित होने से पहले समाप्त हो गया, यह दर्शाता है कि यह धागा काफी समय से बंद था, संभवतः जबकि डोम ने कोणीय टेम्पलेट्स को एक मुख्य धागे में जोड़ा था। पहले $ document.ready () से अंतिम $ टाइमआउट निष्पादन तक का कुल समय लगभग 500 मिलीसेकंड था।

एक असाधारण मामले में जहां एक घटक का मूल्य निर्धारित किया गया था और फिर पाठ () मूल्य को बाद में $ समयबाह्य में बदल दिया गया था, तब तक काम करने तक $ समयबाह्य मूल्य बढ़ाना पड़ता था (भले ही तत्व $ समय के दौरान मिल जाए। )। 3rd पार्टी घटक के भीतर कुछ async पर्याप्त समय बीतने तक पाठ पर पूर्वता लेने के लिए एक मूल्य का कारण बनता है। एक और संभावना $ गुंजाइश है। $ evalAsync, लेकिन कोशिश नहीं की गई थी।

मैं अभी भी उस घटना की तलाश कर रहा हूं जो मुझे बताती है कि डोम पूरी तरह से बस गया है और इसमें हेरफेर किया जा सकता है ताकि सभी मामले काम करें। अब तक एक मनमाना समयबाह्य मूल्य आवश्यक है, जिसका अर्थ है कि सबसे अच्छा यह एक कीचड़ है जो धीमे ब्राउज़र पर काम नहीं कर सकता है। मैंने JQuery के विकल्प जैसे liveQuery और प्रकाशित / सदस्यता की कोशिश नहीं की है जो काम कर सकते हैं, लेकिन निश्चित रूप से शुद्ध कोणीय नहीं हैं।


1

अगर आपको कुछ मिल रहा है getElementById call returns null , तो यह संभवतः इसलिए है क्योंकि फ़ंक्शन चल रहा है, लेकिन आईडी के पास DOM में लोड होने का समय नहीं है।

विल के उत्तर (शीर्ष की ओर) का उपयोग देरी से करें। उदाहरण:

angular.module('MyApp', [])

.controller('MyCtrl', [function() {
    $scope.sleep = (time) => {
        return new Promise((resolve) => setTimeout(resolve, time));
    };
    angular.element(document).ready(function () {
        $scope.sleep(500).then(() => {        
            //code to run here after the delay
        });
    });
}]);

0

कोणीय डॉक्स का उल्लेख करने की कोशिश क्यों न करें https://docs.angularjs.org/api/ng/function/angular_element

angular.element (कॉलबैक)

मैंने इसे अपने $ onInit () {...} फ़ंक्शन के अंदर उपयोग किया है।

 var self = this;

 angular.element(function () {
        var target = document.getElementsByClassName('unitSortingModule');
        target[0].addEventListener("touchstart", self.touchHandler, false);
        ...
    });

इसने मेरे लिए काम किया।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.