ডোম রেন্ডারিং শেষ হওয়ার পরে আমি কীভাবে একটি পরিচালনা চালাতে পারি?


115

আপাতদৃষ্টিতে (কৌনিক জেএস ডক্স পড়ে) সমাধান হিসাবে আমি একটি আপাতদৃষ্টিতে একটি সহজ সমস্যা পেয়েছি ।

আমি একটি কৌণিক জেএস নির্দেশ পেয়েছি যা ডিওএমে একটি ধারকটির উচ্চতা নির্ধারণ করতে অন্যান্য ডিওএম উপাদানগুলির উচ্চতার উপর ভিত্তি করে কিছু গণনা করে।

নির্দেশের অভ্যন্তরে এর অনুরূপ কিছু চলছে:

return function(scope, element, attrs) {
    $('.main').height( $('.site-header').height() -  $('.site-footer').height() );
}

বিষয়টি হ'ল নির্দেশিকাটি যখন চলে তখন $('site-header')খুঁজে পাওয়া যায় না, আমার প্রয়োজন jQuery মোড়ানো DOM উপাদানটির পরিবর্তে একটি খালি অ্যারে ফিরিয়ে দেওয়া।

এমন কোনও কলব্যাক আছে যা আমি আমার নির্দেশের মধ্যে ব্যবহার করতে পারি যা কেবলমাত্র ডিওএম লোড হওয়ার পরে চলে এবং আমি সাধারণ জিক্যুরি সিলেক্টর স্টাইল কোয়েরির মাধ্যমে অন্যান্য ডিওএম উপাদানগুলি অ্যাক্সেস করতে পারি?


1
আপনি সুযোগ ব্যবহার করতে পারেন $ অন () এবং সুযোগ $ নির্গত () কাস্টম ইভেন্টগুলি ব্যবহার করতে। যদিও এটি সঠিক / প্রস্তাবিত পদ্ধতির কিনা তা নিশ্চিত নয়।
তোশ

উত্তর:


137

এটি আপনার $ ('সাইট-শিরোলেখ') কীভাবে নির্মিত তা নির্ভর করে।

আপনি 0 দেরি করে $ টাইমআউট ব্যবহার করার চেষ্টা করতে পারেন । কিছুটা এইরকম:

return function(scope, element, attrs) {
    $timeout(function(){
        $('.main').height( $('.site-header').height() -  $('.site-footer').height() );
    });        
}

এটি কীভাবে কাজ করে তা ব্যাখ্যা: এক , দুটি

$timeoutআপনার নির্দেশে ইনজেকশন করতে ভুলবেন না :

.directive('sticky', function($timeout)

5
ধন্যবাদ, আমি $timeoutনির্দেশগুলিতে প্রবেশ করি নি এমনক্ষণ আমি বয়সের জন্য এটি কাজ করার চেষ্টা করেছি to ডোহ। চিয়ার্স এখন সবকিছুই কাজ করে।
জান্নিস

5
হ্যাঁ, আপনাকে এর $timeoutমতো দিকনির্দেশনায় যেতে হবে :.directive('sticky', function($timeout) { return function (scope, element, attrs, controller) { $timeout(function(){ }); }); };
ভ্লাদিমির স্টারকভ

19
আপনার লিঙ্কযুক্ত ব্যাখ্যাগুলি সময়সীমা ট্রিক জাভা স্ক্রিপ্টে কেন কাজ করে তা ব্যাখ্যা করে তবে অ্যাংুলারজেএস-এর প্রসঙ্গে নয়। থেকে সরকারী ডকুমেন্টেশন : " [...] 4. দ্য $ evalAsync কিউ সময়তালিকা কাজ যা বর্তমান স্ট্যাক ফ্রেমের বাইরে ঘটতে প্রয়োজন করতে ব্যবহৃত হয়, কিন্তু ব্রাউজারের দৃশ্য আগে রেন্ডার। সাধারণত setTimeout (0) সঙ্গে সম্পন্ন করা হয় , কিন্তু সেটটাইমআউট (0) পদ্ধতির ফলে আস্তে আস্তে ভোগা যায় এবং প্রতিটি ইভেন্টের পরে ব্রাউজারটি ভিউটি উপস্থাপন করে বলে দৃশ্যের ঝাঁকুনির কারণ হতে পারে [[...] "(জোর দেওয়া খনি)
আলবার্তো

12
আমি একই ধরণের সমস্যার মুখোমুখি হয়েছি এবং দেখেছি যে আমার নির্দেশ কার্যকর করার আগে DOM লোড করার জন্য আমার প্রায় 300ms প্রয়োজন। আমি এর মতো আপাতদৃষ্টিতে স্বেচ্ছাসেবী সংখ্যাগুলিতে প্লাগিং পছন্দ করি না। আমি নিশ্চিত যে ব্যবহারকারীর উপর নির্ভর করে ডোম লোডিংয়ের গতি পৃথক হবে। তাহলে আমি কীভাবে নিশ্চিত হতে পারি যে 300 মিমি আমার অ্যাপ্লিকেশন ব্যবহার করছে এমন কারও পক্ষে কাজ করবে?
কিপিট্রিয়াল

5
এই উত্তর সম্পর্কে খুব খুশি নয় .. যদিও এটি ওপির প্রশ্নের উত্তর বলে মনে হচ্ছে .. এটি তাদের ক্ষেত্রে খুব নির্দিষ্ট এবং এটি সমস্যার আরও সাধারণ ফর্মের সাথে প্রাসঙ্গিকতা (যেমন একটি ডোম লোড হওয়ার পরে কোনও নির্দেশিকা চালানো) সুস্পষ্ট নয় + এটি কেবল খুব হ্যাকি .. এটিতে কৌণিক সম্পর্কে নির্দিষ্টভাবে কিছুই নেই
অ্যাবড

44

এখানে আমি এটি কীভাবে করছি:

app.directive('example', function() {

    return function(scope, element, attrs) {
        angular.element(document).ready(function() {
                //MANIPULATE THE DOM
        });
    };

});

1
এমনকি কৌণিক.এলিমেন্টের প্রয়োজন হবে না কারণ উপাদান ইতিমধ্যে সেখানে পাওয়া যায়:element.ready(function(){
টিমহ্যাক 22

1
@ টিএমএইচসি 22 এলিমেন্টটি ডোমমেন্টের একটি রেফারেন্স যা নির্দেশকে ট্রিগার করেছিল, আপনার সুপারিশের ফলে ডকুমেন্ট অবজেক্টের পৃষ্ঠাগুলির কোনও ডোমলমেন্ট রেফারেন্স হবে না।
tobius

যে সঠিকভাবে কাজ করে না। এই পদ্ধতির মাধ্যমে আমি অফসেটউইথ = 0 পাচ্ছি
আলেক্সি শ।

37

সম্ভবত লেখকের আর আমার উত্তর প্রয়োজন হবে না। তবুও, সম্পূর্ণতার জন্য আমি অন্য ব্যবহারকারীদের এটি দরকারী মনে হতে পারে বলে মনে করি। $(window).load()প্রত্যাশিত ফাংশনের দেহের অভ্যন্তরে ব্যবহার করা সর্বাধিক সহজ সমাধান simple (বিকল্পভাবে আপনি ব্যবহার করতে পারেন document.ready। আপনার যদি সমস্ত চিত্রের প্রয়োজন হয় তবে এটি সত্যই নির্ভর করে)।

$timeoutআমার নম্র মতামত ব্যবহার করা খুব দুর্বল বিকল্প এবং কিছু ক্ষেত্রে ব্যর্থ হতে পারে।

আমি ব্যবহার করব এমন সম্পূর্ণ কোডটি এখানে:

.directive('directiveExample', function(){
   return {
       restrict: 'A',
       link: function($scope, $elem, attrs){

           $(window).load(function() {
               //...JS here...
           });
       }
   }
});

1
এটি "কিছু ক্ষেত্রে ব্যর্থ হতে পারে" কেন আপনি ব্যাখ্যা করতে পারেন? আপনি কি মামলা মানে?
রাইটার

6
আপনি ধরে নিচ্ছেন যে jQuery এখানে উপলব্ধ।
জোনাথন ক্রেমিন

3
@ জোনাথনক্রিমিন জিকুয়েরি নির্বাচন করা ওপি অনুসারে বিষয়টি হ'ল
নিক দেভেরাক্স

1
এটি দুর্দান্ত কাজ করে তবে যদি এমন কোনও পোস্ট থাকে যা নির্দেশের সাহায্যে নতুন আইটেম তৈরি করে তবে উইন্ডো লোড প্রাথমিক লোডের পরে আগুন নেবে না এবং তাই সঠিকভাবে কাজ করবে না।
ব্রায়ান স্কট

@ ব্রায়ানস্কট - আমি প্রাথমিক পৃষ্ঠা রেন্ডারিংয়ের জন্য $ (উইন্ডো)। লোডের সংমিশ্রণটি ব্যবহার করেছি (আমার ব্যবহারের ক্ষেত্রে এম্বেড করা ফন্ট ফাইলগুলির অপেক্ষায় ছিল) এবং তারপরে উপাদানটি স্যুইচিং ভিউয়ের যত্ন নিতে প্রস্তুত।
aaaaaa

8

একটি ngcontentloadedইভেন্ট আছে, আমার মনে হয় আপনি এটি ব্যবহার করতে পারেন

.directive('directiveExample', function(){
   return {
       restrict: 'A',
       link: function(scope, elem, attrs){

                $$window = $ $window


                init = function(){
                    contentHeight = elem.outerHeight()
                    //do the things
                }

                $$window.on('ngcontentloaded',init)

       }
   }
});

21
আপনি কি ব্যাখ্যা $ $windowকরছেন?
ক্যাটফিশ

2
কিছু কফিস্ক্রিপ্টের মতো দেখাচ্ছে, সম্ভবত এটি $ ($ উইন্ডো) এবং $ উইন্ডোটি নির্দেশে ইনজেকশনের মাধ্যমে বোঝানো হয়েছিল
এমডব

5

যদি আপনি বাহ্যিক সংস্থার কারণে $ সময়সীমা ব্যবহার করতে না পারেন এবং সময় সহ কোনও নির্দিষ্ট সমস্যার কারণে কোনও নির্দেশনা ব্যবহার করতে না পারেন তবে সম্প্রচারটি ব্যবহার করুন।

যোগ $scope.$broadcast("variable_name_here"); আকাঙ্ক্ষিত বহিরাগত রিসোর্স পর বা দীর্ঘ নিয়ামক চলমান / নির্দেশ সম্পন্ন করেছে।

আপনার বাহ্যিক সংস্থান লোড হওয়ার পরে নীচে যুক্ত করুন।

$scope.$on("variable_name_here", function(){ 
   // DOM manipulation here
   jQuery('selector').height(); 
}

উদাহরণস্বরূপ একটি স্থগিত HTTP অনুরোধের প্রতিশ্রুতিতে।

MyHttpService.then(function(data){
   $scope.MyHttpReturnedImage = data.image;
   $scope.$broadcast("imageLoaded");
});

$scope.$on("imageLoaded", function(){ 
   jQuery('img').height(80).width(80); 
}

2
এটি সমস্যার সমাধান করবে না, যেহেতু লোড হওয়া ডেটার অর্থ এই নয় যে তারা ইতিমধ্যে ডিওএম-তে রেন্ডার করা হয়েছে, এমনকি যদি তারা ডিওএম উপাদানগুলির সাথে আবদ্ধ সঠিক স্কোপ ভেরিয়েবলগুলিতে থাকে। স্কোপে লোড হওয়ার মুহুর্ত এবং ডোমে রেন্ডার আউটপুটের মধ্যে একটি টাইমস্প্যান রয়েছে।
রেনা স্ট্যাল্ডার

1

আমারও একই সমস্যা ছিল এবং আমার সমাধানটি এখানে ভাগ করে নিতে চাই।

আমি নিম্নলিখিত এইচটিএমএল আছে:

<div data-my-directive>
  <div id='sub' ng-include='includedFile.htm'></div>
</div>

সমস্যা: পিতামাতার ডিভের নির্দেশনার লিঙ্ক-ফাংশনে আমি সন্তানের ডিভি # সাব উপস্থাপন করতে চাই। তবে এটি আমাকে একটি খালি অবজেক্ট দিয়েছে কারণ নির্দেশনার লিঙ্ক ফাংশনটি যখন দৌড়েছিল তখন এনজি-অন্তর্ভুক্ত শেষ হয়নি। তাই প্রথমে আমি $ টাইমআউট দিয়ে একটি নোংরা কাজ করেছি, যা কাজ করেছে তবে বিলম্ব-পরামিতি ক্লায়েন্টের গতির উপর নির্ভর করে (এটি কেউ পছন্দ করে না)।

কাজ কিন্তু নোংরা:

app.directive('myDirective', [function () {
    var directive = {};
    directive.link = function (scope, element, attrs) {
        $timeout(function() {
            //very dirty cause of client-depending varying delay time 
            $('#sub').css(/*whatever*/);
        }, 350);
    };
    return directive;
}]);

পরিষ্কার সমাধান এখানে:

app.directive('myDirective', [function () {
    var directive = {};
    directive.link = function (scope, element, attrs) {
        scope.$on('$includeContentLoaded', function() {
            //just happens in the moment when ng-included finished
            $('#sub').css(/*whatever*/);
        };
    };
    return directive;
}]);

হতে পারে এটি কাউকে সাহায্য করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.