أعمل على طلب سحب (PR) إلى إضافة Poll.
أحاول عرض مكون Glimmer كعقدة ورقة في شجرة الأدوات (widget tree) كما فعلت عدة مرات من قبل، ولكنني أواجه هذا الخطأ الغريب الذي لم أره من قبل:
TypeError: this.parentMountWidgetComponent is undefined
يحدث هذا السطر:
setComponentTemplate(template, component);
this._componentInfo = {
element,
component,
@tracked data: this.data,
setWrapperElementAttrs: (attrs) =>
this.updateElementAttrs(element, attrs),
};
this.parentMountWidgetComponent.mountChildComponent(this._componentInfo);
}
updateElementAttrs(element, attrs) {
for (let [key, value] of Object.entries(attrs)) {
if (key === "class") {
value = [element[INITIAL_CLASSES], value].filter(Boolean).join(" ");
}
if ([null, undefined].includes(value)) {
element.removeAttribute(key);
يبدو أن this.widget?._findView() || this._emberView
هو undefined.
(this.widget موجود)
if ([null, undefined].includes(value)) {
element.removeAttribute(key);
} else {
element.setAttribute(key, value);
}
}
}
get parentMountWidgetComponent() {
return this.widget?._findView() || this._emberView;
}
}
RenderGlimmer.prototype.type = "Widget";
/**
* Define a widget shim which renders a Glimmer template. Designed for incrementally migrating
* a widget-based UI to Glimmer. Widget attrs will be made available to your template at `@data`.
* For more details, see documentation for the RenderGlimmer class.
* @param name - the widget's name (which can then be used in `.attach` elsewhere)
الكود الخاص بي في مراحله المبكرة جدًا موجود هنا:
}
},
});
createWidget("discourse-poll-option-dropdown", {
tagName: "div.irv-dropdown",
buildKey: (attrs) => `discourse-poll-option-dropdown-${attrs.option.id}`,
html(attrs) {
return [
new RenderGlimmer(
this,
"div.irv-dropdown-content",
hbsCli`<DropdownSelectBox @value={{@data.value}} @content={{data.content}} @onChange={{action (mut data.selectRank)}} @options={{hash showCaret=false filterable=false none="poll.options.irv.abstain" }} class="poll-option-dropdown"/>`,
{
...attrs,
value: 0 || "poll.options.irv.abstain", //option.value
content: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
selectRank: this.selectRank.bind(this),
}
),
هل استخدام RenderGlimmer في هذا السياق قانوني؟
إعجاب واحد (1)
هل يعتمد هذا على وجود خاصية لدى أحد الأسلاف؟
this._findAncestorWithProperty("_emberView")
والتي تعود بقيمة غير محددة.
أو أن العنصر نفسه يحتوي على خاصية _emberView (وهو ما لا يفعله)
أفترض أن السلف كان يجب أن تكون لديه هذه الخاصية هنا:
const t0 = Date.now();
const args = this.args || this.buildArgs();
const opts = {
model: this.model,
dirtyKeys: this.dirtyKeys,
};
const newTree = new this._widgetClass(args, this.register, opts);
newTree._rerenderable = this;
newTree._emberView = this;
const patches = diff(this._tree || this._rootNode, newTree);
traverseCustomWidgets(this._tree, (w) => w.willRerenderWidget());
this.beforePatch();
this._rootNode = patch(this._rootNode, patches);
this.afterPatch();
this._tree = newTree;
حسنًا، مزيد من المعلومات.
عند عرض الاستطلاع (كمجموعة من الأدوات المصغرة)، يتم تنفيذ هذا السطر، ولكن عند العودة للتصويت، لا يتم تنفيذه، وبالتالي لسبب ما لا يوجد سلف لديه _emberView (أو لم يتم العثور عليه).
قد يكون مصدر هذه المشكلة هو أن الأداة المصغرة لا يتم إعادة عرضها أبدًا:
rerenderWidget() {
لا يتم تشغيلها مرة أخرى على الرغم من إضافة مجموعة جديدة من الأدوات المصغرة … لذا لم يتم تعيين هذه الخاصية أبدًا.
… وبالتالي قد يكون الحل هو جدولة إعادة عرض عند الضغط على زر التصويت …
toggleResults() {
**this.scheduleRerender();**
this.state.showResults = !this.state.showResults;
},
… لا، هذا لا يحل المشكلة.
مزيد من المعلومات:
_findAncestorWithProperty(property) {
let widget = this;
while (widget) {
const value = widget[property];
if (value) {
return widget;
}
widget = widget.parentWidget;
}
}
هذا يبحث في الشجرة عن الخاصية.
في العرض الأولي، تظهر هذه الخاصية عند مستوى post-stream.
ولكن بطريقة ما يبدو أن الأدوات المصغرة تفقد أسلافها …
حسنًا، لقد تعمقت قليلاً:
const refreshAction = dirtyOpts.onRefresh;
if (refreshAction) {
this.sendWidgetAction(refreshAction, dirtyOpts.refreshArg);
}
}
return this.draw(h, this.attrs, this.state);
}
_findAncestorWithProperty(property) {
let widget = this;
while (widget) {
const value = widget[property];
if (value) {
return widget;
}
widget = widget.parentWidget;
}
}
هذا هو التسلسل الهرمي الذي يحدث فيه اجتياز الأداة:
discourse-poll-option-dropdown-245da0f65a66dbd539bcd27e501d759a [widget.js:250:14](webpack://discourse/widgets/widget.js)
discourse-poll-option-245da0f65a66dbd539bcd27e501d759a [widget.js:250:14](webpack://discourse/widgets/widget.js)
poll-container-poll-1247 [widget.js:250:14](webpack://discourse/widgets/widget.js)
poll-poll-1247
الآن، آخر أداة موجودة… ليس لها أداة أصل.
parentWidget هو undefined.
والأمر المثير للاهتمام هو أنه لا يحتوي على خاصية “_emberView”، لذا تكون النتيجة undefined.
لذلك، لا يتم العثور على الخاصية وفي تلك النقطة يتوقف الاجتياز.
3 إعجابات
david
(David Taylor)
17 أبريل 2024، 12:26م
4
تعد إضافة الاستطلاع غير عادية بعض الشيء من حيث أن الأداة المساعدة مثبتة داخل HTML المُعالج للمنشور، بدلاً من تثبيتها مباشرة داخل قالب Ember عبر المكون \u003cMountWidget. لذلك، ربما نحتاج إلى إضافة بعض المنطق الإضافي هنا… سألقي نظرة
شكرًا للإبلاغ يا @merefield !
3 إعجابات
david
(David Taylor)
18 أبريل 2024، 2:29م
6
أعتقد أنه إذا قمنا بدمج هذا، فيجب أن يجعل الكود الخاص بك يعمل يا @merefield
main ← widget-through-cooked
opened 02:12PM - 18 Apr 24 UTC
In this case, the top-level widget being glued must have a `_postCookedWidget` a… ttribute.
إنه ليس جميلاً بشكل خاص، ولكني أعتقد أنه لا بأس بما أن هذا موقف نادر جدًا، ونأمل أن نزيل كل هذه الأشياء المتعلقة بالـ widget/RenderGlimmer في المستقبل القريب جدًا
4 إعجابات
شكرا ديفيد. نعم، من المنطقي أن يكون الحل الوسط كافياً في الوقت الحالي
سأقوم باختباره بمجرد دمجه (وسيتعين علي تحديث نسختي! )
4 إعجابات
أقدر حقًا سرعة إنجاز هذا يا ديفيد.
أؤكد أن هذا يعمل الآن بالنسبة لي.
سأقوم بالنشر هنا إذا واجهت أي مشاكل أخرى مع هذا الترتيب.
(تنويه لقطة الشاشة: أيام مبكرة جدًا لهذا المشروع!)
إعجابَين (2)
system
(system)
تم إغلاقه في
19 مايو 2024، 11:15ص
10
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.