مشكلة تتبع الهيكل الداخلي

أقوم بإدراج مكون Glimmer في topic-above-footer-buttons. يحاول مكون Glimmer هذا عرض بعض البيانات الوصفية حول الموضوع. أقوم بتسلسل هذه إلى topic.my_metadata

عند تحديث البيانات الوصفية من مهمة خلفية (!)، يتم تحديث الموضوع عبر MessageBus.publish(\"/topic/#{topic.id}\", { reload_topic: true, refresh_stream: true })

الآن يتم تحديث هذا بشكل صحيح في القالب:

{{this.args.topic.my_metadata.status}}

ومع ذلك، عندما أصل إليه عبر getter

get statusMessage() {
  return this.args.topic.my_metadata.status;
}

ثم

{{ this.statusMessage }}

لا يتم التحديث.

(وينطبق الشيء نفسه على جميع الـ getters التي لدي والتي تعتمد على this.args.topic.my_metadata بأي شكل من الأشكال. وهي المشكلة الفعلية).

ما الذي أفعله بشكل خاطئ؟

لقد جربت بالفعل الكثير، بما في ذلك تعريف أحداث مخصصة، ونسخ topic.my_metadata إلى @tracked metadata ثم استخدام this.metadata، وما إلى ذلك.

إعجاب واحد (1)

أعتقد أنك تضمن فقط إعادة تقييم getter إذا كانت إحدى القيم التي يعتمد عليها يتم تتبعها (وتتغير)

لذا في هذه الحالة أعتقد أن {{this.args.topic.my_metadata.status}} أفضل، على الرغم من أنه يجب عليك كتابتها هكذا: {{@topic.my_metadata.status}}

إعجابَين (2)

حسنًا، الأمر ليس مسألة “أفضل” أو لا، هناك الكثير من المنطق في جافاسكريبت يقوم بتقييم البيانات الوصفية وعلى سبيل المثال يقرر ما إذا كان يجب عرض زر، مثل

get showButton() {
   // قم ببعض العمليات المكثفة على this.args.topic.my_metadata.foo و this.args.topic.my_metadata.bar
}

لذلك أنا بحاجة إلى الـ getters وأحتاج إليها لإعادة التقييم بطريقة ما.

بالإضافة إلى ذلك، تقول وثائق Glimmer أن args وقيمها يتم تتبعها تلقائيًا.

إذا كان القالب قادرًا على تتبعها تلقائيًا، فلماذا لا يستطيع الـ getter؟

حتى هذا يعمل، بتمرير البيانات الوصفية كوسيط

{{this.getStatus this.args.topic.my_metadata}}

مع

  getStatus(arg) {
    return arg.status;
  }

هذا جزء مؤسف من تحويلنا في منتصف الطريق من نظام التفاعل “الكلاسيكي” في Ember (get/set/computed) إلى @tracked / native-getters في “octane”.

لذا، كما نوقش أعلاه، المشكلة في مثالك هي أنك تصل إلى خاصية غير @tracked من native getter.

الوصول إلى المسار الكامل مباشرة من القالب سيعمل، على الرغم من أنه كما تقول، فإنه يحد من المنطق المتاح.

بدلاً من ذلك، سيسمح استخدام .get() لنظام التتبع التلقائي الجديد في Ember بالعمل ضد الخصائص الكلاسيكية (أي غير @tracked).

لذا في هذه الحالة، سيكون:

get statusMessage() {
  return this.args.topic.get("my_metadata.status");
}
4 إعجابات

شكرا ديفيد

هل يمكنك أيضًا حل هذا باستخدام @computed أم أن ذلك ممنوع؟

  @computed('args.topic.my_metadata.status')
  get statusMessage() {
    // قد يكون هذا أكثر تعقيدًا بكثير
    return this.args.topic.my_metadata.status;
  }

أعتقد أن هذا سيكون له فائدة تخزين النتيجة مؤقتًا إذا كان الحساب مهمًا.

(من الواضح أنه بسيط في هذا المثال ولكنه شيء أشار إليه @RGJ)

@computed هو جزء من نظام التفاعل الكلاسيكي في Ember. لم يتم إيقافه رسميًا، لكننا نحاول تجنب إضافته إلى التعليمات البرمجية الجديدة.

إذا كان الـ getter الخاص بك معقدًا بما يكفي لاستحقاق التخزين المؤقت، فيمكنك استخدام @cached:

import { cached } from "@glimmer/tracking";

...

@cached
get statusMessage() {
  // قد يكون هذا أكثر تعقيدًا
  return this.args.topic.my_metadata.status;
}
إعجاب واحد (1)

هذا يعمل بشكل رائع. شكرًا لك على إنقاذ ما تبقى من يوم الجمعة الخاص بي @david !!! أقدر ذلك كثيرًا!!

إعجابَين (2)

تم إغلاق هذا الموضوع تلقائيًا بعد 30 يومًا من آخر رد. لم تعد الردود الجديدة مسموح بها.