অ্যাংুলারজেএস লোড করা শেষ হলে ইভেন্ট প্রেরণ


114

সমস্ত নির্দেশ সংকলন / লিঙ্কিং সম্পন্ন করার পরে পৃষ্ঠা লোডিং / বুটস্ট্র্যাপিংয়ের সমাপ্তি সনাক্ত করার সর্বোত্তম উপায়টি কী তা অবাক করে দিয়েছিলেন।

ইতিমধ্যে কোন অনুষ্ঠান আছে? আমার কি বুটস্ট্র্যাপ ফাংশনটি ওভারলোড করা উচিত?

উত্তর:


204

শুধু একটি কুঁচক: এনজি ক্লক নির্দেশিকা কীভাবে তা দেখছে না? স্পষ্টতই ngCloak নির্দেশাবলী জিনিসগুলি লোড হওয়ার পরে সামগ্রী প্রদর্শন করতে পরিচালিত করে। আমি বাজি ধরেছি এনজি ক্লোকের দিকে তাকানো সঠিক উত্তরটি নিয়ে যাবে ...

1 ঘন্টা পরে সম্পাদনা করুন: ঠিক আছে, আমি ngCloak তাকিয়েছিলাম এবং এটি সত্যিই সংক্ষিপ্ত। এটি যা স্পষ্টভাবে বোঝায় তা হ'ল ile {টেমপ্লেট}} এক্সপ্রেশনগুলি মূল্যায়ন না করা (অর্থাৎ এটি লোড করা টেমপ্লেট) অবধি সংকলন ফাংশনটি কার্যকর করা হবে না, এভাবে এনজিক্লোক নির্দেশনার দুর্দান্ত কার্যকারিতা।

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

সম্পাদনা করুন, ২৩ ঘন্টা পরে: ঠিক আছে, তাই আমি কিছু গবেষণা করেছি, এবং আমি আমার নিজের প্রশ্নও জিজ্ঞাসা করেছি । আমি যে প্রশ্নটি জিজ্ঞাসা করেছি তা অপ্রত্যক্ষভাবে এই প্রশ্নের সাথে সম্পর্কিত ছিল, তবে এটি কাকতালীয়ভাবে আমাকে উত্তরটির দিকে নিয়ে যায় যা এই প্রশ্নের সমাধান করে।

উত্তরটি হ'ল আপনি একটি সহজ নির্দেশিকা তৈরি করতে পারেন এবং নির্দেশকের লিঙ্ক ফাংশনে আপনার কোডটি রাখতে পারেন, যা আপনার উপাদান প্রস্তুত / লোড হওয়ার পরে (বেশিরভাগ ব্যবহারের ক্ষেত্রে, নীচে বর্ণিত) চালিত হবে। ক্রম এবং লিঙ্ক ফাংশনগুলি কার্যকর করা হয় সেই ক্রমের জোশের বর্ণনার ভিত্তিতে ,

আপনার যদি এই মার্কআপ থাকে:

<div directive1>
  <div directive2>
    <!-- ... -->
  </div>
</div>

তারপরে অ্যাঙ্গুলারজেএস একটি নির্দিষ্ট ক্রমে নির্দেশমূলক ফাংশন পরিচালনা করে দিকনির্দেশগুলি তৈরি করবে:

directive1: compile
  directive2: compile
directive1: controller
directive1: pre-link
  directive2: controller
  directive2: pre-link
  directive2: post-link
directive1: post-link

ডিফল্টরূপে একটি সরল "লিঙ্ক" ফাংশন একটি পোস্ট-লিঙ্ক, সুতরাং আপনার বাহ্যিক ডিরেক্টরি 1 এর লিঙ্ক ফাংশন অভ্যন্তরীণ ডিরেক্টরি 2 এর লিঙ্ক ফাংশনটি সঞ্চালিত না হওয়া পর্যন্ত চলবে না। সে কারণেই আমরা বলি যে পোস্ট লিংকে ডিওএম ম্যানিপুলেশন করা কেবল নিরাপদ। সুতরাং মূল প্রশ্নের দিকে, বাইরের দিকনির্দেশকের লিঙ্ক ফাংশন থেকে শিশু নির্দেশকের অন্তর্নিহিত এইচটিএমএল অ্যাক্সেস করার কোনও সমস্যা থাকতে হবে না, যদিও গতিশীলভাবে প্রবেশ করা বিষয়বস্তু অবশ্যই সংকলন করতে হবে, যেমন উপরে বলা হয়েছে।

এ থেকে আমরা উপসংহারে পৌঁছাতে পারি যে যখন সবকিছু প্রস্তুত / সংকলিত / সংযুক্ত / লোড হয় তখন আমরা কেবল আমাদের কোডটি কার্যকর করার জন্য একটি নির্দেশনা তৈরি করতে পারি:

    app.directive('ngElementReady', [function() {
        return {
            priority: -1000, // a low number so this directive loads after all other directives have loaded. 
            restrict: "A", // attribute only
            link: function($scope, $element, $attributes) {
                console.log(" -- Element ready!");
                // do what you want here.
            }
        };
    }]);

এখন আপনি যা করতে পারেন তা হ'ল অ্যাপ্লিকেশনটির মূল উপাদানটির উপরে এনজিলেটমেন্ট রেডি নির্দেশিকা রাখুন, এবং console.logলোড হওয়ার পরে উইলটি ফায়ার করবে:

<body data-ng-app="MyApp" data-ng-element-ready="">
   ...
   ...
</body>

এটা যে সহজ! কেবল একটি সাধারণ নির্দেশনা তৈরি করুন এবং এটি ব্যবহার করুন। ;)

আপনি এটিকে আরও কাস্টমাইজ করতে পারেন যাতে এটি যুক্ত করে এটি একটি এক্সপ্রেশন (অর্থাত্ কোনও ফাংশন) সম্পাদন $scope.$eval($attributes.ngElementReady);করতে পারে:

    app.directive('ngElementReady', [function() {
        return {
            priority: Number.MIN_SAFE_INTEGER, // execute last, after all other directives if any.
            restrict: "A",
            link: function($scope, $element, $attributes) {
                $scope.$eval($attributes.ngElementReady); // execute the expression in the attribute.
            }
        };
    }]);

তারপরে আপনি এটিকে যে কোনও উপাদানটিতে ব্যবহার করতে পারেন:

<body data-ng-app="MyApp" data-ng-controller="BodyCtrl" data-ng-element-ready="bodyIsReady()">
    ...
    <div data-ng-element-ready="divIsReady()">...<div>
</body>

কেবলমাত্র নিশ্চিত হয়ে নিন যে আপনার উপাদানগুলি (নিয়ামক হিসাবে) আপনার উপাদানটি যে অধীনে চলেছে তার কার্যকারিতা (যেমন বডিআইএসআরেডি এবং ডিভিআইএসআরেডি) সংজ্ঞায়িত হয়েছে।

ক্যাভেটস: আমি বলেছি এটি বেশিরভাগ ক্ষেত্রে কাজ করবে । এনজিআরপিট এবং এনজিআইএফ-এর মতো নির্দিষ্ট নির্দেশাবলী ব্যবহার করার সময় সাবধানতা অবলম্বন করুন। তারা তাদের নিজস্ব সুযোগ তৈরি করে এবং আপনার নির্দেশিকাটি আগুন নাও পেতে পারে। উদাহরণস্বরূপ, আপনি যদি আমাদের নতুন এনজিএলিমেন্টি রেডি নির্দেশকে এমন কোনও উপাদানের উপরে রাখেন যার মধ্যেও এনজিআইএফ রয়েছে, এবং এনজিআইফের শর্তটি মিথ্যা হিসাবে মূল্যায়ন করে, তবে আমাদের এনজিলেটমেন্ট রেডি নির্দেশটি লোড হবে না। অথবা, উদাহরণস্বরূপ, আপনি যদি আমাদের নতুন এনজিএলিমেন্টি রেডি নির্দেশকে এমন কোনও উপাদানের উপরে রাখেন যার একটি এনজিইনক্লুড ডাইরেক্টিভও থাকে তবে এনজিআইনক্লুডের টেমপ্লেট উপস্থিত না থাকলে আমাদের নির্দেশটি লোড হবে না। আপনি এগুলি কয়েকটি একই উপাদানের উপরে রাখার পরিবর্তে নির্দেশাবলী বাসা বাঁধে তা নিশ্চিত করে আপনি এই সমস্যাগুলির কয়েকটি পেতে পারেন। উদাহরণস্বরূপ, এটি করে:

<div data-ng-element-ready="divIsReady()">
    <div data-ng-include="non-existent-template.html"></div>
<div>

এর পরিবর্তে:

<div data-ng-element-ready="divIsReady()" data-ng-include="non-existent-template.html"></div>

NgElementReady নির্দেশিকা পরবর্তী উদাহরণগুলিতে সংকলিত হবে তবে এর লিঙ্ক ফাংশনটি কার্যকর করা হবে না। দ্রষ্টব্য: নির্দেশিকা সর্বদা সংকলিত থাকে তবে উপরের মতো নির্দিষ্ট পরিস্থিতিতে নির্ভর করে তাদের লিঙ্ক ফাংশন সর্বদা কার্যকর করা হয় না।

সম্পাদনা করুন, কয়েক মিনিট পরে:

ওহ, এবং প্রশ্নের পুরোপুরি উত্তর দেওয়ার জন্য আপনি এখন $emitবা $broadcastআপনার ইভেন্টটি ng-element-readyবৈশিষ্ট্যটিতে কার্যকর হওয়া এক্সপ্রেশন বা ফাংশন থেকে করতে পারেন । :) উদ:

<div data-ng-element-ready="$emit('someEvent')">
    ...
<div>

সম্পাদনা করুন, আরও কয়েক মিনিট পরে:

@ সাতমোরুনের উত্তরগুলি খুব কার্যকর, তবে কেবলমাত্র প্রাথমিক লোডের জন্য। এখানে একটি খুব দরকারী এসও প্রশ্ন রয়েছে যা লিঙ্ক ফাংশন app.run, এবং অন্যদের সহ অর্ডার জিনিসগুলি কার্যকর করা হয় তা বর্ণনা করে । সুতরাং, আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে app.runভাল হতে পারে তবে নির্দিষ্ট উপাদানগুলির পক্ষে নয়, এই ক্ষেত্রে লিঙ্কের কাজগুলি আরও ভাল।

সম্পাদনা, পাঁচ মাস পরে, 17 অক্টোবর 8:11 পিএসটি:

এটি অবিচ্ছিন্নভাবে লোড হওয়া পার্টিয়ালগুলির সাথে কাজ করে না। আপনার পার্টিয়ালগুলিতে আপনাকে হিসাবরক্ষণ যুক্ত করতে হবে (উদাহরণস্বরূপ একটি উপায় হ'ল প্রতিটি আংশিক বিষয়বস্তুটি লোড হয়ে যাওয়ার পরে তা ট্র্যাক করে রাখার পরে একটি ইভেন্ট নির্গত করা যাতে প্যারেন্ট স্কোপটি গণনা করতে পারে যে কতগুলি পার্টিয়াল লোড হয়েছে এবং অবশেষে এটির প্রয়োজন কী করে সমস্ত পার্টিয়াল লোড হওয়ার পরে করুন)।

সম্পাদনা, 23 অক্টোবর রাত 10:52 পিএসটি:

কোনও চিত্র লোড হওয়ার পরে আমি কিছু কোড ফায়ার করার জন্য একটি সহজ নির্দেশনা দিয়েছিলাম:

/*
 * This img directive makes it so that if you put a loaded="" attribute on any
 * img element in your app, the expression of that attribute will be evaluated
 * after the images has finished loading. Use this to, for example, remove
 * loading animations after images have finished loading.
 */
  app.directive('img', function() {
    return {
      restrict: 'E',
      link: function($scope, $element, $attributes) {
        $element.bind('load', function() {
          if ($attributes.loaded) {
            $scope.$eval($attributes.loaded);
          }
        });
      }
    };
  });

সম্পাদনা, 24 অক্টোবর 12:48 পিএসটি:

আমি আমার আসল ngElementReadyনির্দেশকে উন্নত করে এর নামকরণ করেছি whenReady

/*
 * The whenReady directive allows you to execute the content of a when-ready
 * attribute after the element is ready (i.e. done loading all sub directives and DOM
 * content except for things that load asynchronously like partials and images).
 *
 * Execute multiple expressions by delimiting them with a semi-colon. If there
 * is more than one expression, and the last expression evaluates to true, then
 * all expressions prior will be evaluated after all text nodes in the element
 * have been interpolated (i.e. {{placeholders}} replaced with actual values). 
 *
 * Caveats: if other directives exists on the same element as this directive
 * and destroy the element thus preventing other directives from loading, using
 * this directive won't work. The optimal way to use this is to put this
 * directive on an outer element.
 */
app.directive('whenReady', ['$interpolate', function($interpolate) {
  return {
    restrict: 'A',
    priority: Number.MIN_SAFE_INTEGER, // execute last, after all other directives if any.
    link: function($scope, $element, $attributes) {
      var expressions = $attributes.whenReady.split(';');
      var waitForInterpolation = false;

      function evalExpressions(expressions) {
        expressions.forEach(function(expression) {
          $scope.$eval(expression);
        });
      }

      if ($attributes.whenReady.trim().length == 0) { return; }

      if (expressions.length > 1) {
        if ($scope.$eval(expressions.pop())) {
          waitForInterpolation = true;
        }
      }

      if (waitForInterpolation) {
        requestAnimationFrame(function checkIfInterpolated() {
          if ($element.text().indexOf($interpolate.startSymbol()) >= 0) { // if the text still has {{placeholders}}
            requestAnimationFrame(checkIfInterpolated);
          }
          else {
            evalExpressions(expressions);
          }
        });
      }
      else {
        evalExpressions(expressions);
      }
    }
  }
}]);

উদাহরণস্বরূপ, someFunctionকোনও উপাদান লোড হওয়া এবং {{placeholders}}এখনও প্রতিস্থাপন না করা অবস্থায় এটি আগুন দেওয়ার জন্য এটি ব্যবহার করুন :

<div when-ready="someFunction()">
  <span ng-repeat="item in items">{{item.property}}</span>
</div>

someFunctionসমস্ত item.propertyস্থানধারক প্রতিস্থাপনের আগে ডাকা হবে ।

আপনি চান যতগুলি এক্সপ্রেশন মূল্যায়ন করুন এবং এর মূল্যায়ন হওয়ার trueজন্য অপেক্ষা করার জন্য শেষ প্রকাশটি করুন {{placeholders}}:

<div when-ready="someFunction(); anotherFunction(); true">
  <span ng-repeat="item in items">{{item.property}}</span>
</div>

someFunctionএবং প্রতিস্থাপনের anotherFunctionপরে বরখাস্ত করা হবে {{placeholders}}

এটি কেবলমাত্র প্রথম বার কোনও উপাদান লোড হওয়ার সময় কাজ করে, ভবিষ্যতের পরিবর্তনের জন্য নয়। $digestপ্রাথমিকভাবে স্থানধারকগুলি প্রতিস্থাপনের পরে যদি কোনও ঘটনা ঘটে থাকে তবে এটি পছন্দসই হিসাবে কাজ করতে পারে না (ডেটা বদলানো বন্ধ না হওয়া পর্যন্ত একটি ডাইজেস্ট 10 বার পর্যন্ত ঘটতে পারে)। এটি বেশিরভাগ ব্যবহারের ক্ষেত্রে উপযুক্ত হবে।

সম্পাদনা, 31 অক্টোবর সন্ধ্যা 7:26 পিএসটি:

ঠিক আছে, এটি সম্ভবত আমার শেষ এবং চূড়ান্ত আপডেট। এটি সম্ভবত ব্যবহারের 99.999 টির জন্য কাজ করবে:

/*
 * The whenReady directive allows you to execute the content of a when-ready
 * attribute after the element is ready (i.e. when it's done loading all sub directives and DOM
 * content). See: /programming/14968690/sending-event-when-angular-js-finished-loading
 *
 * Execute multiple expressions in the when-ready attribute by delimiting them
 * with a semi-colon. when-ready="doThis(); doThat()"
 *
 * Optional: If the value of a wait-for-interpolation attribute on the
 * element evaluates to true, then the expressions in when-ready will be
 * evaluated after all text nodes in the element have been interpolated (i.e.
 * {{placeholders}} have been replaced with actual values).
 *
 * Optional: Use a ready-check attribute to write an expression that
 * specifies what condition is true at any given moment in time when the
 * element is ready. The expression will be evaluated repeatedly until the
 * condition is finally true. The expression is executed with
 * requestAnimationFrame so that it fires at a moment when it is least likely
 * to block rendering of the page.
 *
 * If wait-for-interpolation and ready-check are both supplied, then the
 * when-ready expressions will fire after interpolation is done *and* after
 * the ready-check condition evaluates to true.
 *
 * Caveats: if other directives exists on the same element as this directive
 * and destroy the element thus preventing other directives from loading, using
 * this directive won't work. The optimal way to use this is to put this
 * directive on an outer element.
 */
app.directive('whenReady', ['$interpolate', function($interpolate) {
  return {
    restrict: 'A',
    priority: Number.MIN_SAFE_INTEGER, // execute last, after all other directives if any.
    link: function($scope, $element, $attributes) {
      var expressions = $attributes.whenReady.split(';');
      var waitForInterpolation = false;
      var hasReadyCheckExpression = false;

      function evalExpressions(expressions) {
        expressions.forEach(function(expression) {
          $scope.$eval(expression);
        });
      }

      if ($attributes.whenReady.trim().length === 0) { return; }

    if ($attributes.waitForInterpolation && $scope.$eval($attributes.waitForInterpolation)) {
        waitForInterpolation = true;
    }

      if ($attributes.readyCheck) {
        hasReadyCheckExpression = true;
      }

      if (waitForInterpolation || hasReadyCheckExpression) {
        requestAnimationFrame(function checkIfReady() {
          var isInterpolated = false;
          var isReadyCheckTrue = false;

          if (waitForInterpolation && $element.text().indexOf($interpolate.startSymbol()) >= 0) { // if the text still has {{placeholders}}
            isInterpolated = false;
          }
          else {
            isInterpolated = true;
          }

          if (hasReadyCheckExpression && !$scope.$eval($attributes.readyCheck)) { // if the ready check expression returns false
            isReadyCheckTrue = false;
          }
          else {
            isReadyCheckTrue = true;
          }

          if (isInterpolated && isReadyCheckTrue) { evalExpressions(expressions); }
          else { requestAnimationFrame(checkIfReady); }

        });
      }
      else {
        evalExpressions(expressions);
      }
    }
  };
}]);

এটি ব্যবহার করুন

<div when-ready="isReady()" ready-check="checkIfReady()" wait-for-interpolation="true">
   isReady will fire when this {{placeholder}} has been evaluated
   and when checkIfReady finally returns true. checkIfReady might
   contain code like `$('.some-element').length`.
</div>

অবশ্যই, এটি সম্ভবত অনুকূলিত করা যেতে পারে, তবে আমি কেবল এটি এ ছেড়ে দেব। অনুরোধএনিমেশন ফ্রেমটি দুর্দান্ত is


3
সত্যিই এই সমস্ত "ডেটা" উপসর্গ দিয়ে বিরক্তিকর। আমি আনন্দিত যে আমি সেগুলি নিজে ব্যবহার করি না।
স্টলসভিক

1
@ স্টলভিক হে, হ্যাঁ, সবচেয়ে আধুনিক ব্রাউজারগুলিতে তাদের প্রয়োজন হয় না।
trusktr

49
এই উত্তরে দেওয়া সময় এবং প্রচেষ্টার পরিমাণের জন্য ভোট গ্রহণের উপযুক্ত। চমৎকার কাজ!
GordyD

8
উত্তম উত্তর, তবে দয়া করে সমস্ত "সম্পাদনা করুন" লাইনগুলি সরিয়ে এবং আপনার উত্তরটিকে কিছুটা পুনর্গঠন করার বিষয়টি বিবেচনা করুন। সম্পাদনা ইতিহাসটি আপনার উত্তরের নীচে "সম্পাদিত ..." লিঙ্কের মাধ্যমে উপলব্ধ এবং এটি পড়ার সময় বিকৃত হয়।
ব্যবহারকারী 247702

2
উত্স কোডটি সত্যই সহায়ক হবে। এবং আপনি যদি এনটিএম এ জনসাধারণ করতে পারেন, তবে এটি নিখুঁত হবে। সত্যই সুন্দর উত্তর, সত্যই সুন্দরভাবে ব্যাখ্যা করা হয়েছে, এতে প্রচুর পরিশ্রমের জন্য +1।
tfrascaroli

38

ইন এর জন্য দস্তাবেজangular.Module , একটি এন্ট্রি বর্ণনা করেন runফাংশন:

কাজটি নিবন্ধ করার জন্য এই পদ্ধতিটি ব্যবহার করুন যা ইনজেক্টরটি সমস্ত মডিউল লোড করে নেওয়ার পরে সম্পাদন করা উচিত।

সুতরাং আপনার যদি এমন কিছু মডিউল থাকে যা আপনার অ্যাপ্লিকেশন:

var app = angular.module('app', [/* module dependencies */]);

মডিউলগুলি লোড হওয়ার পরে আপনি স্টাফ চালাতে পারেন:

app.run(function() {
  // Do post-load initialization stuff here
});

সম্পাদনা: উদ্ধার করার জন্য ম্যানুয়াল সূচনা

সুতরাং এটি উল্লেখ করা হয়েছে যে runডম প্রস্তুত এবং সংযুক্ত হওয়ার পরে কল হবে না। $injectorরেফারেন্সযুক্ত মডিউলটির জন্য ng-appতার সমস্ত নির্ভরতা লোড করা হলে এটি ডাকা হয় , যা ডিওএম সংকলন পদক্ষেপ থেকে পৃথক।

আমি ম্যানুয়াল আরম্ভের দিকে আরেকবার নজর রেখেছি এবং মনে হচ্ছে এটি কৌশলটি করা উচিত।

আমি উদাহরণস্বরূপ একটি ভাঁজ তৈরি করেছি

এইচটিএমএল সহজ:

<html>
    <body>
        <test-directive>This is a test</test-directive>
    </body>
</html>

একটি অভাব নোট করুন ng-app। এবং আমার কাছে একটি নির্দেশ রয়েছে যা কিছু ডিওএম ম্যানিপুলেশন করবে, যাতে আমরা জিনিসগুলির ক্রম এবং সময় সম্পর্কে নিশ্চিত করতে পারি।

যথারীতি একটি মডিউল তৈরি করা হয়েছে:

var app = angular.module('app', []);

এবং এখানে নির্দেশাবলী:

app.directive('testDirective', function() {
    return {
        restrict: 'E',
        template: '<div class="test-directive"><h1><div ng-transclude></div></h1></div>',
        replace: true,
        transclude: true,
        compile: function() {
            console.log("Compiling test-directive");
            return {
                pre: function() { console.log("Prelink"); },
                post: function() { console.log("Postlink"); }
            };
        }
    };
});

আমরা test-directiveট্যাগটি divক্লাসের সাথে প্রতিস্থাপন করতে যাচ্ছি test-directiveএবং এর বিষয়বস্তুটি একটিতে মুড়ে দেব h1

আমি একটি সংকলন ফাংশন যুক্ত করেছি যা প্রাক এবং পোস্ট উভয়ই লিংক ফাংশন প্রদান করে যাতে এই জিনিসগুলি কখন চালিত হয় তা আমরা দেখতে পারি।

কোডটির বাকী অংশটি এখানে:

// The bootstrapping process

var body = document.getElementsByTagName('body')[0];

// Check that our directive hasn't been compiled

function howmany(classname) {
    return document.getElementsByClassName(classname).length;
}

আমরা কিছু করার আগে, test-directiveডোমের কোনও শ্রেণীর সাথে কোনও উপাদান থাকা উচিত নয় এবং আমাদের কাজ শেষ হওয়ার পরে সেখানে 1 হওয়া উচিত।

console.log('before (should be 0):', howmany('test-directive'));

angular.element(document).ready(function() {
    // Bootstrap the body, which loades the specified modules
    // and compiled the DOM.
    angular.bootstrap(body, ['app']);

    // Our app is loaded and the DOM is compiled
    console.log('after (should be 1):', howmany('test-directive'));
});

এটা বেশ সোজা। দস্তাবেজটি প্রস্তুত angular.bootstrapহয়ে গেলে আপনার অ্যাপ্লিকেশনটির মূল উপাদান এবং মডিউল নামের একটি অ্যারে দিয়ে কল করুন।

প্রকৃতপক্ষে, আপনি মডিউলে কোনও runফাংশন সংযুক্ত করলেapp , আপনি দেখতে পাবেন যে কোনও সংকলন সংঘটিত হওয়ার আগেই এটি চলমান।

আপনি যদি ফ্রিডলটি চালনা করেন এবং কনসোলটি দেখেন, আপনি নিম্নলিখিতগুলি দেখতে পাবেন:

before (should be 0): 0 
Compiling test-directive 
Prelink
Postlink
after (should be 1): 1 <--- success!

2
ধন্যবাদ @ স্যাচমোরুন! তবে চালান () লিঙ্কিং অংশের সমাপ্তির আগে সম্পাদন করে - কিছু কনসোল.লগ দিয়ে এটি যাচাই করেছে।
লাইওর

নিজেই কৌতূহলী ছিলাম ... আমার একটি নির্দেশনা রয়েছে যা কিছু jQuery DOM প্লাগইন প্রয়োগের জন্য আগুন দেয়, runনির্দেশের আগে আগুন জ্বলে ওঠে এবং যখন আগুন চালায় তখন এইচটিএমএল সব কিছু থাকে না
Charlietfl

@ চর্লিটএফএল - আমি ম্যানুয়াল বুটস্ট্র্যাপিংয়ের জন্য কিছুটা খুঁড়েছি, এবং প্রশ্নটি যা খুঁজছে তা পাওয়ার এটি আসলে একটি খুব সহজ উপায়। আমি আমার মূল উত্তরে একটি দীর্ঘ দীর্ঘ সম্পাদনা যুক্ত করেছি।
সাতমুরুন

5
আমি দেখতে পেয়েছি যে $timeout( initMyPlugins,0)আমার নির্দেশের মধ্যে কাজগুলি ব্যবহার করে, আমার যে সমস্ত এইচটিএমএল প্রয়োজন তা সেখানে রয়েছে
Charlietfl

: @satchmorun, এই ফলো-আপ দেখতে stackoverflow.com/questions/14989161/...
Lior

16

কোনও পৃষ্ঠার লোডিং শেষ হয়ে গেলে কৌণিক সংকেত দেওয়ার কোনও উপায় সরবরাহ করেনি, কারণ "সমাপ্ত" আপনার আবেদনের উপর নির্ভর করে । উদাহরণস্বরূপ, আপনার যদি পার্টিয়ালের শ্রেণিবদ্ধ গাছ থাকে, অন্যটি লোড করে। "সমাপ্তি" এর অর্থ হ'ল এটি সমস্ত লোড হয়ে গেছে। যে কোনও ফ্রেমওয়ার্ক আপনার কোড বিশ্লেষণ করতে এবং বুঝতে পেরেছিল যে সবকিছু শেষ হয়েছে বা এখনও অপেক্ষা করা কঠিন হতে পারে। তার জন্য, এটি যাচাই করতে এবং এটি নির্ধারণ করতে আপনাকে অ্যাপ্লিকেশন-নির্দিষ্ট যুক্তি সরবরাহ করতে হবে।


14

আমি এমন একটি সমাধান নিয়ে এসেছি যা কৌণিক সূচনা সম্পন্ন হওয়ার পরে মূল্যায়নে তুলনামূলকভাবে নির্ভুল।

নির্দেশটি হ'ল:

.directive('initialisation',['$rootScope',function($rootScope) {
            return {
                restrict: 'A',
                link: function($scope) {
                    var to;
                    var listener = $scope.$watch(function() {
                        clearTimeout(to);
                        to = setTimeout(function () {
                            console.log('initialised');
                            listener();
                            $rootScope.$broadcast('initialised');
                        }, 50);
                    });
                }
            };
        }]);

তারপরে এটি কেবলমাত্র bodyউপাদানটির একটি বৈশিষ্ট্য হিসাবে যুক্ত করা যেতে পারে এবং তারপরে ব্যবহারের জন্য শোনো$scope.$on('initialised', fn)

এটি ধরে নিয়েই কাজ করে যে যখন আর কোনও ডাইজেস্ট চক্র নেই তখন অ্যাপ্লিকেশনটি আরম্ভ করা হয়। $ ঘড়িকে প্রতিটি ডাইজেস্ট চক্র বলা হয় এবং তাই টাইমার শুরু হয় (সেটটাইমআউট নয় $ টাইমআউট যাতে নতুন ডাইজেস্ট চক্রটি ট্রিগার হয় না)। যদি কোনও ডাইজেস্ট চক্র সময়সীমার মধ্যে না ঘটে তবে অ্যাপ্লিকেশনটি আরম্ভ করা হয়েছে বলে ধরে নেওয়া হয়।

এটি স্পষ্টমুরুনস দ্রবণের মতো স্পষ্টতই সঠিক নয় (সম্ভবত এটি একটি ডাইজেস্ট চক্র সময়সীমার চেয়ে বেশি সময় নেয়) তবে আমার সমাধানটির আপনাকে মডিউলগুলি ট্র্যাক করার প্রয়োজন নেই যা এটি পরিচালনা করা এত সহজ করে তোলে (বিশেষত বৃহত প্রকল্পগুলির জন্য) )। যাইহোক, আমার প্রয়োজনীয়তার জন্য যথেষ্ট সঠিক বলে মনে হচ্ছে। আশা করি এটা সাহায্য করবে.


দুর্দান্ত সমাধান। প্রকল্পগুলির জন্য যখন এক বা দুটি সংক্ষেপিত ফাইলের সমস্ত কোড খুব ভালভাবে কাজ করে।
মার্ক্লোভ

1
এটি দুর্দান্ত সমাধান case যদি আপনার কাছে jquery তে প্রচুর কোড থাকে এবং আপনি কোডটি কৌণিক ধাপে ধাপে ধাপে রূপান্তরিত করার চেষ্টা করছেন যা এটি সঠিক ধারণা দেয়।
মঙ্গেশ পিম্পলকর

11

আপনি যদি কৌনিক ইউআই রাউটার ব্যবহার করেন তবে আপনি $viewContentLoadedইভেন্টটি শুনতে পারবেন ।

"OM ভিউ কনটেন্টলয়েড - বরখাস্ত একবার ভিড লোড হয়ে গেলে, ডম রেন্ডার হয়ে যাওয়ার পরে view দর্শনটির '$ সুযোগ' ইভেন্টটি প্রকাশ করে।" - লিঙ্ক

$scope.$on('$viewContentLoaded', 
function(event){ ... });

3
$ সুযোগ। $ ওয়াচ ('$ ভিউকন্টেন্টলয়েড', ফাংশন () আমার জন্য কৌশলটি তৈরি করেছে
লুই XIV

2
'আপনার হওয়া উচিত' এর জন্য ডাউনভোটেড। আমি যদি বলি "যদি আপনি কৌণিক পরিবর্তে প্রতিক্রিয়া ব্যবহার করেন (তবে আপনার যা হওয়া উচিত) ..."? এই বাস্তুতন্ত্র আইএমএইচওতে থাকার খুব একটা মনোভাব নয়।
ভ্যালেন্টিন ওয়েজিলিঙ্ক

আপনি ভালেন ঠিক আছেন আমি আমার পক্ষপাতিত্ব অপসারণ করতে আমার উত্তর সম্পাদনা করেছি।
জর্ডান স্কোল

1
আমার জন্য কাজ! ধন্যবাদ. আমি আসলে এটি আমার রান ফাংশনে যুক্ত করেছি, তারপরে $ স্কোপটি $ রুটস্কোপে পরিবর্তিত করেছি।
জেডিভিস 26'16

2
অ্যাংুলার বিশ্ববিদ্যালয় যেমন অন্য একটি উত্তরের দিকে ইঙ্গিত করেছে, $ ভিউকন্টেন্টলয়েড সম্ভবত সেখানে ছিল না তবে এখন এটি বিল্ট-ইন এনজিআরট সরবরাহকারীতে ঠিক একইভাবে কাজ করে। এই বিষয়টি মাথায় রেখে, আমি মনে করি এটি হ'ল দ্রুত, সাধারণ, পাঠযোগ্য উত্তর অনেক (সর্বাধিক?) ভবিষ্যতের পাঠকরা খুঁজবেন।
কেভিন ক্রমলে

3

আমি জিকিউরির সাথে কৌণিক ডিওএম হেরফের পর্যবেক্ষণ করেছি এবং আমি আমার অ্যাপের জন্য একটি সমাপ্তি স্থাপন করেছি (আমার অ্যাপ্লিকেশন-বিমূর্তের জন্য আমার প্রয়োজন এমন এক ধরণের পূর্বনির্ধারিত এবং সন্তোষজনক পরিস্থিতি) উদাহরণস্বরূপ আমি আশা করি যে আমার এনজি-রিপিটারটি 7 ফলাফল উত্পন্ন করবে এবং আমি সেখানে এই উদ্দেশ্যে setInterval এর সাহায্যে একটি পর্যবেক্ষণ ফাংশন সেট করবে।

$(document).ready(function(){

  var interval = setInterval(function(){

  if($("article").size() == 7){
     myFunction();
     clearInterval(interval);
  }

  },50);

});

3
আমি এই কাজ না। স্টাফগুলি ঘটছে কিনা তা পরীক্ষা করার জন্য অন্তরগুলি ব্যবহার করা ভাল অনুশীলন, অপ্রকাশ্য নয় এবং জিনিসগুলি ঘটানোর অন্যান্য উপায় রয়েছে। টাইমারগুলি এমন কংক্রিট কাজগুলি করার জন্য যা নির্দিষ্ট সময়সীমার পরে ঘটতে হবে, যখন সামগ্রী বা ফলাফল প্রস্তুত হয় তখন "অনুমান" করার জন্য নয়।
ডুয়াদওয়াদ

কৌণিক প্ল্যাটফর্মের বিরুদ্ধে jquery টাইমার ব্যবহার করা পাল্টা উত্পাদনশীল- কৌণিকের একটি টাইমআউট ক্লাস রয়েছে এবং আপনার এটি ব্যবহার করা উচিত অন্যথায় আপনি দুটি কাঠামো বিস্তৃত করছেন এবং এটি খুব দ্রুত বিভ্রান্তিকর হয়ে ওঠে।
দোয়াদওয়াদ

3

আপনি যদি এনজিআরউট মডিউলটি ব্যবহার না করেন , তবে আপনার কাছে $ ভিউকন্টেন্টলয়েড ইভেন্ট নেই।

আপনি অন্য নির্দেশিকা পদ্ধতি ব্যবহার করতে পারেন:

    angular.module('someModule')
        .directive('someDirective', someDirective);

    someDirective.$inject = ['$rootScope', '$timeout']; //Inject services

    function someDirective($rootScope, $timeout){
        return {
            restrict: "A",
            priority: Number.MIN_SAFE_INTEGER, //Lowest priority
            link    : function(scope, element, attr){
                $timeout(
                    function(){
                        $rootScope.$emit("Some:event");
                    }
                );
            }
        };
    }

তদনুসারে ট্রস্ক্র্টরের উত্তর অনুসারে এর সর্বনিম্ন অগ্রাধিকার রয়েছে। প্লাস $ টাইমআউট আঙ্গুলের কলব্যাক বাস্তবায়নের আগে পুরো ইভেন্ট লুপের মধ্য দিয়ে চলে।

$ রুটস্কোপ ব্যবহার করা হয়েছে, কারণ এটি অ্যাপ্লিকেশনটির যে কোনও সুযোগে নির্দেশিকা রাখার অনুমতি দেয় এবং কেবল প্রয়োজনীয় শ্রোতাদের জানিয়ে দেয়।

$ রুটস্কোপ। $ ইমিট সমস্ত শ্রোতার জন্য একটি ইভেন্টে আগুন দেবে। রুটস্কোপ। কেবল শ্রোতাদের জন্য। আকর্ষণীয় অংশ যে $ rootScope। $ সম্প্রচারের সব $ rootScope অবহিত করবে। $ ভাল $ সুযোগ হিসেবে উপর। $ শ্রোতাদের ওপর উত্স


2

কৌণিক দল এবং এই গিথুব ইস্যু অনুসারে :

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

এর ভিত্তিতে, মনে হয় এটি নির্ভরযোগ্য উপায়ে করা বর্তমানে সম্ভব নয় , অন্যথায় অ্যাঙ্গুলারটি ইভেন্টটি বাক্সের বাইরে সরবরাহ করত।

অ্যাপ্লিকেশনটিকে বুটস্ট্র্যাপিং বলতে বোঝায় যে ডাইজেস্ট চক্রটি মূল স্কোপে চলমান, এবং ডাইজেস্ট চক্র সমাপ্ত ইভেন্টও নেই।

কৌণিক 2 ডিজাইন ডক্স অনুসারে :

একাধিক হজমের কারণে, মডেলটি স্থিতিশীল যে উপাদানটি নির্ধারণ এবং অবহিত করা অসম্ভব। এটি কারণ নোটিফিকেশন ডেটা পরিবর্তন করতে পারে যা বাধ্যতামূলক প্রক্রিয়া পুনরায় আরম্ভ করতে পারে।

এর মতে, এঙ্গুলার 2-এ পুনর্লিখনের জন্য কেন সিদ্ধান্ত নেওয়া হয়েছিল তা হ'ল এটি সম্ভব নয়।


2

আমার একটি খণ্ড ছিল যা মূল আংশিক পরে / রাউটিংয়ের মাধ্যমে এসে লোড হচ্ছিল।

আমি এই subpartial বোঝা পরে একটি ফাংশন চালানোর প্রয়োজন ছিল এবং আমি একটি নতুন নির্দেশিকা লিখতে চান না এবং আপনি একটি বোকামি ব্যবহার করতে পারেন ভেবেছি ngIf

প্যারেন্ট আংশিকের নিয়ামক:

$scope.subIsLoaded = function() { /*do stuff*/; return true; };

উপ-পার্টিশনের এইচটিএমএল

<element ng-if="subIsLoaded()"><!-- more html --></element>

1

আপনি যদি সার্ভার-সাইড ডেটা (জেএসপি, পিএইচপি) দিয়ে জেএস তৈরি করতে চান তবে আপনি কোনও যুক্তিতে আপনার যুক্তি যুক্ত করতে পারেন, যখন আপনার নিয়ামকটি লোড হবে তখন স্বয়ংক্রিয়ভাবে লোড হবে।

অতিরিক্তভাবে, আপনি যদি সমস্ত নির্দেশাবলী সংকলন / লিঙ্কিং সম্পন্ন করার সময় প্রতিক্রিয়া জানাতে চান, তবে আপনি উপরের যথাযথ প্রস্তাবিত সমাধানগুলি আরম্ভের যুক্তিতে যুক্ত করতে পারেন।

module.factory('YourControllerInitService', function() {

    // add your initialization logic here

    // return empty service, because it will not be used
    return {};
});


module.controller('YourController', function (YourControllerInitService) {
});

0

এগুলি সমস্ত দুর্দান্ত সমাধান, তবে আপনি যদি বর্তমানে রাউটিং ব্যবহার করছেন তবে আমি খুঁজে পেয়েছি এই সমাধানটি সবচেয়ে সহজ এবং ন্যূনতম পরিমাণের কোড হিসাবে প্রয়োজনীয়। রুটটি ট্রিগার করার আগে পূর্ণ হওয়ার প্রতিশ্রুতির জন্য অপেক্ষা করতে 'সমাধান' সম্পত্তিটি ব্যবহার করা। যেমন

$routeProvider
.when("/news", {
    templateUrl: "newsView.html",
    controller: "newsController",
    resolve: {
        message: function(messageService){
            return messageService.getMessage();
    }
}

})

সম্পূর্ণ ডক্সের জন্য এখানে ক্লিক করুন - কে স্কট অ্যালেনের কাছে ক্রেডিট


0

আমি এই উদাহরণ দিয়ে আপনাকে সাহায্য করতে পারে হতে পারে

কাস্টম ফেন্সিবক্সে আমি অন্তরবিচ্ছিন্ন মানগুলির সাথে সামগ্রীগুলি প্রদর্শন করি।

পরিষেবাটিতে, "ওপেন" অভিনব বাক্স পদ্ধতিতে, আমি করি

open: function(html, $compile) {
        var el = angular.element(html);
     var compiledEl = $compile(el);
        $.fancybox.open(el); 
      }

ile সংকলিত তথ্য সংকলন প্রদান করে। আপনি সংকলিত তথ্য পরীক্ষা করতে পারেন

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