Angular.js: أمر ربط وحدات التحكم ($ onChanges يُستدعى قبل $ onInit)

تم إنشاؤها على ١٦ ديسمبر ٢٠١٦  ·  9تعليقات  ·  مصدر: angular/angular.js

هل تريد طلب ميزة أو الإبلاغ عن خطأ ؟
لا أعرف ما إذا كان مطلوبًا أم أنه خطأ

ما هو السلوك الحالي؟
أول مكالمة $onChanges تتم قبل $onInit الواحد.
مع التكوين الافتراضي للزاوية 1.6 (التعيين المسبق = خطأ) ، من الممكن تهيئة حالات وحدة التحكم في الوظيفة $onInit ، نظرًا لعدم إمكانية الوصول إلى الارتباطات بعد في المُنشئ.

ما هو السلوك المتوقع؟
أعتقد أنه سيكون من المنطقي أكثر استدعاء $onInit أولاً.
لا ينبغي أن يفعل Angular أي شيء أثناء عدم تهيئة وحدة التحكم بشكل كامل.

ما هو الدافع / حالة الاستخدام لتغيير السلوك؟
إذا استخدمنا كائنات من المفترض إنشاؤها في الوظيفة $onInit في الوظيفة $onChanges ؛ سيكون لدينا خطأ في المكالمة الأولى ، لأنه لم تتم تهيئة وحدة التحكم بعد.
قد يكون الحل هو تهيئة تلك الكائنات داخل المُنشئ ، لكننا سنهيئ وحدة التحكم في مكانين مختلفين ...

ما إصدارات Angular وأي متصفح / نظام تشغيل متأثر بهذه المشكلة؟ يرجى أيضًا الاختبار باستخدام أحدث الإصدارات الثابتة واللقطات (https://code.angularjs.org/snapshot/).
إصدار 1.6 الزاوي

works as expected

التعليق الأكثر فائدة

الغرض من ذلك (بشكل أساسي لمطابقة سلوك Angular 2+). في حالة فقدها ، يمكنك التحقق مما إذا كانت المكالمة الأولى (قبل $ onInit) من $onChanges ، عن طريق التحقق من القيمة المرجعة لطريقة isFirstChange() لأي من SimpleChange كائنات

{
  ...
  bindings: {foo: '<'},
  controller: function SomeController() {
    this.$onChanges = function(changes) {
      if (changes.foo.isFirstChange()) {
        // `$onInit()` has not been called yet...
      }
    };
  }
}

#

أعترف أن ردة فعلي الأولى كانت هي نفسها. من منظور النموذج العقلي ، من الأسهل التفكير في أن $onInit() هو أول شيء يحدث في وحدة التحكم ؛ ثم $onChanges() و $onChanges() و $onChanges() و أخيرًا $onDestroy() .

ولكن إذا فكرت في الأمر ، فيجب تقييم الارتباطات وتعيينها إلى مثيل وحدة التحكم قبل استدعاء $onInit . ومن خلال القيام بذلك ، يتم الكشف عن تغيير في القيم (غير المحددة سابقًا) ، والتي بدورها يجب الإبلاغ عنها عبر $onChanges .

الإغلاق ، لأن هذا يعمل كما هو متوقع (أو على الأقل كما هو مقصود: wink :).

ال 9 كومينتر

الغرض من ذلك (بشكل أساسي لمطابقة سلوك Angular 2+). في حالة فقدها ، يمكنك التحقق مما إذا كانت المكالمة الأولى (قبل $ onInit) من $onChanges ، عن طريق التحقق من القيمة المرجعة لطريقة isFirstChange() لأي من SimpleChange كائنات

{
  ...
  bindings: {foo: '<'},
  controller: function SomeController() {
    this.$onChanges = function(changes) {
      if (changes.foo.isFirstChange()) {
        // `$onInit()` has not been called yet...
      }
    };
  }
}

#

أعترف أن ردة فعلي الأولى كانت هي نفسها. من منظور النموذج العقلي ، من الأسهل التفكير في أن $onInit() هو أول شيء يحدث في وحدة التحكم ؛ ثم $onChanges() و $onChanges() و $onChanges() و أخيرًا $onDestroy() .

ولكن إذا فكرت في الأمر ، فيجب تقييم الارتباطات وتعيينها إلى مثيل وحدة التحكم قبل استدعاء $onInit . ومن خلال القيام بذلك ، يتم الكشف عن تغيير في القيم (غير المحددة سابقًا) ، والتي بدورها يجب الإبلاغ عنها عبر $onChanges .

الإغلاق ، لأن هذا يعمل كما هو متوقع (أو على الأقل كما هو مقصود: wink :).

شكرا جزيلا على إجابتك ، فالأمر أوضح الآن :)

أفهم أن هذا مقصود ، فماذا لو سجلنا تعريف الدالة $ onChanges () داخل $ onInit ().

bharatpatil ، يجب أن تعمل في AngularJS (1.x.) لكنها لن تعمل في Angular (2+).

إذا (Changes.foo.isFirstChange ()) {
// $onInit() لم يتم استدعاؤه بعد ...
}

gkalpak أعتقد أن هذه الحجة خاطئة. تضمن الطريقة binding.isFirstChange() فقط استدعاء الربط المرتبط في المرة الأولى. فكر في ربط تمت تهيئته بعد أن تستغرق مكالمة الخدمة وقتًا طويلاً. في هذه الحالة ، يجب استدعاء طريقة controller.$onInit طريقة controller.$onChanges . هل انا مخطئ

دائمًا ما يكون للربط قيمة في البداية (يمكن أن تكون undefined ) ، والتي تختلف دائمًا عن القيمة التي تمت تهيئتها مسبقًا. وبالتالي ، سيتم استدعاء $onChanges() دائمًا بـ changes.foo قبل استدعاء $onInit() .

ليس من المنطقي أن يكون للربط قيمة قبل أن تتم تهيئته. هذا هو تعريف القاموس لكلمة التهيئة (قم بتعيين القيم الأولية). لا يمكنك تغيير شيء ما إذا لم يكن له قيمة أولية. أعتقد أن التسمية خاطئة هنا وغير طبيعية.

لا أتذكر موقفًا لم أجبر فيه على كتابة شيء مثل هذا الرمز:

$onChanges(changesObj: { [index: string]: angular.IChangesObject; })  {
   if (!this.isInitialized) return;
   ...
}

استدعاء "التغييرات" قبل "التهيئة" لا معنى له.

على قدم المساواة مع المسار مع Angular ... لماذا يتوقع أي شخص أن يحدث البادئة قبل التغييرات؟

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات