<LightDarkImg /> 를 사용할 때, 문제의 원인을 가늠할 수 있는 실질적인 정보가 전혀 없는 이해할 수 없는 오류가 발생합니다.
오류:
index.js:1755
Uncaught (in promise) TypeError: eC(...) is not a function
at index.js:1755:48
at index.js:64:37
at X (index.js:416:5)
at k (index.js:62:16)
at index.js:1759:46
at index.js:64:37
at X (index.js:416:5)
at k (index.js:62:16)
at m.get (index.js:84:60)
at Array Iterator.next (<anonymous>)
at A.getValue (index.js:244:86)
at index.js:222:52
at index.js:64:37
at X (index.js:416:5)
at k (index.js:62:16)
at index.js:1841:47
at index.js:64:37
at X (index.js:416:5)
at k (index.js:62:16)
at Object.evaluate (index.js:807:13)
at Object.evaluate (index.js:103:106)
at tr.evaluateSyscall (index.js:2873:20)
at tr.evaluateInner (index.js:2852:64)
at tr.evaluateOuter (index.js:2849:10)
at tH.next (index.js:4167:45)
at tH._execute (index.js:4157:21)
at tH.execute (index.js:4133:41)
at tj.handleException (index.js:3450:19)
at tR.handleException (index.js:3592:52)
at tF.throw (index.js:3414:16)
at G.evaluate (index.js:565:42)
at tF._execute (index.js:3401:34)
at tF.execute (index.js:3393:17)
at tU.rerender (index.js:3610:8)
at tq.render (index-BCp6wOJU.js:4639:55)
at index-BCp6wOJU.js:4934:16
at eX (index.js:2414:7)
at tG._renderRoots (index-BCp6wOJU.js:4914:7)
at tG._renderRootsTransaction (index-BCp6wOJU.js:4962:12)
at tG._revalidate (index-BCp6wOJU.js:4995:10)
at invoke (index.js:262:14)
at m.flush (index.js:180:11)
at g.flush (index.js:334:19)
at q._end (index.js:762:32)
at q.end (index.js:565:10)
at q._run (index.js:806:14)
at q._join (index.js:783:19)
at q.join (index.js:605:17)
at Array.<anonymous> (index-BCp6wOJU.js:4728:26)
at q._trigger (index.js:860:21)
at q._end (index.js:775:16)
at _boundAutorunEnd (index.js:499:12)
제 코드:
{{#if (and this.logoImg this.darkLogoImg)}}
<div class="category-logo aspect-image">
<LightDarkImg
@lightImg={{this.logoImg}}
@darkImg={{this.darkLogoImg}}
/>
</div>
{{/if}}
메서드는 다음과 같습니다:
get logoImg() {
if (settings.show_category_logo && this.args.category.uploaded_logo) {
console.log(this.args.category.uploaded_logo.url);
return this.args.category.uploaded_logo;
} else if (
settings.show_category_logo &&
settings.show_parent_category_logo &&
this.args.category.parentCategory &&
this.args.category.parentCategory.uploaded_logo
) {
return this.args.category.parentCategory.uploaded_logo;
} else if (settings.show_site_logo && this.siteSettings.logo_small) {
return this.siteSettings.logo_small;
} else {
return false;
}
}
get darkLogoImg() {
if (settings.show_dark_mode_category_logo && this.args.category.uploaded_logo_dark.url) {
console.log(this.args.category.uploaded_logo_dark.url);
return this.args.category.uploaded_logo_dark;
} else if (
settings.show_dark_mode_category_logo &&
settings.show_parent_category_dark_mode_logo &&
this.args.category.parentCategory &&
this.args.category.parentCategory.uploaded_logo_dark
) {
return this.args.category.parentCategory.uploaded_logo_dark;
} else if (settings.show_site_logo && this.siteSettings.logo_small) {
return this.siteSettings.logo_small;
} else {
return this.args.category.uploaded_logo; // 다크 모드 로고가 업로드되지 않은 경우, 일반 로고를 사용합니다.
}
}
aforementioned LightDarkImg 컴포넌트(내 파일 시스템에 복제된 것)에서 모든 것을 로깅하고 있으며, 이미지 URL이 올바르게 출력됩니다. <img> 태그를 사용할 때도 올바르게 표시됩니다.
아무 아이디어가 있을까요? 감사합니다.
david
(David Taylor)
10월 7, 2025, 8:54오전
2
임포트 포함 전체 파일을 공유해 주실 수 있나요?
코드가 정상적으로 동작할 때까지 하나씩 줄여가는 방법을 권장합니다. 예를 들어, 에러가 {{#if에서 오는 건가요? (and에서? 아니면 getter 중 하나에서?
문제없습니다. 전체 파일은 다음과 같습니다:
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import LightDarkImg from "discourse/components/light-dark-img";
import { ajax } from "discourse/lib/ajax";
import icon from "discourse/helpers/d-icon";
import { and, not } from "truth-helpers";
export default class CategoryHeader extends Component {
@service siteSettings;
@service site;
@tracked full_category_description;
constructor() {
super(...arguments);
this.getFullCatDesc();
}
get ifParentCategory() {
if (this.args.category.parentCategory) {
return true;
}
}
get showCatDesc() {
if (settings.show_category_description) {
return true;
}
}
get catDesc() {
return this.args.category.description;
}
async getFullCatDesc() {
try {
let cd = await ajax(`${this.args.category.topic_url}.json`);
this.full_category_description = cd.post_stream.posts[0].cooked;
} catch {}
}
get showFullCatDesc() {
if (settings.show_full_category_description) {
return true;
}
}
get logoImg() {
if (settings.show_category_logo && this.args.category.uploaded_logo) {
console.log(this.args.category.uploaded_logo.url);
return this.args.category.uploaded_logo;
} else if (
settings.show_category_logo &&
settings.show_parent_category_logo &&
this.args.category.parentCategory &&
this.args.category.parentCategory.uploaded_logo
) {
return this.args.category.parentCategory.uploaded_logo;
} else if (settings.show_site_logo && this.siteSettings.logo_small) {
return this.siteSettings.logo_small;
} else {
return false;
}
}
get darkLogoImg() {
if (settings.show_dark_mode_category_logo && this.args.category.uploaded_logo_dark.url) {
console.log(this.args.category.uploaded_logo_dark.url);
return this.args.category.uploaded_logo_dark;
} else if (
settings.show_dark_mode_category_logo &&
settings.show_parent_category_dark_mode_logo &&
this.args.category.parentCategory &&
this.args.category.parentCategory.uploaded_logo_dark
) {
return this.args.category.parentCategory.uploaded_logo_dark;
} else if (settings.show_site_logo && this.siteSettings.logo_small) {
return this.siteSettings.logo_small;
} else {
return this.args.category.uploaded_logo; // 다크 모드 로고가 업로드되지 않은 경우, 일반 로고를 사용합니다
}
}
get ifParentProtected() {
if (
this.args.category.parentCategory &&
(
this.args.category.parentCategory.permission === null ||
this.args.category.parentCategory.read_restricted
)
) {
return true;
}
}
get ifProtected() {
if (
this.args.category.permission === null ||
this.args.category.read_restricted
) {
return true;
}
}
get lockIcon() {
return settings.category_lock_icon || "lock";
}
get showHeader() {
const isException =
this.args.category &&
settings.hide_category_exceptions
.split("|")
.includes(String(this.args.category.id));
const hideMobile = !settings.show_mobile && this.site.mobileView;
const subCat =
!settings.show_subcategory_header && this.args.category.parentCategory;
const noDesc =
!settings.hide_if_no_category_description &&
!this.args.category.description_text;
const path = window.location.pathname;
return (
/^\/c\//.test(path) && !isException && !noDesc && !subCat && !hideMobile
);
}
get getHeaderStyle() {
let headerStyle = "";
if (settings.header_style === "box") {
headerStyle +=
"border-left: 6px solid #" + this.args.category.color + ";";
}
if (settings.header_style === "banner") {
headerStyle +=
"background-color: #" +
this.args.category.color +
"; color: #" +
this.args.category.text_color +
";";
}
if (settings.show_parent_category_background_image) {
if (this.args.category.parentCategory) {
if (
settings.header_background_image !== "outside" &&
this.args.category.parentCategory.uploaded_background
) {
headerStyle +=
"background-image: url(" +
this.args.category.parentCategory.uploaded_background.url +
");";
}
} else if (this.args.category.uploaded_background) {
if (settings.header_background_image !== "outside") {
headerStyle +=
"background-image: url(" +
this.args.category.uploaded_background.url +
");";
}
}
} else {
if (this.args.category.uploaded_background) {
if (settings.header_background_image !== "outside") {
headerStyle +=
"background-image: url(" +
this.args.category.uploaded_background.url +
");";
}
}
}
return headerStyle + " display: block; margin-bottom: 1em;";
}
get aboutTopicUrl() {
if (settings.show_read_more_link && this.args.category.topic_url) {
return settings.read_more_link_text;
}
}
get inlineReadMore() {
return (settings.inline_read_more && (settings.show_category_description || settings.show_full_category_description) && settings.show_read_more_link);
}
<template>
{{#if this.showHeader}}
<div
class="category-title-header category-banner-{{@category.slug}}"
style={{this.getHeaderStyle}}
>
<div class="category-title-contents">
{{#if (and this.logoImg this.darkLogoImg)}}
<div class="category-logo aspect-image">
<LightDarkImg
@lightImg={{this.logoImg}}
@darkImg={{this.darkLogoImg}}
/>
</div>
{{/if}}
<div class="category-title-name" style={{if (not (this.logoImg)) "padding: 0 !important;"}}>
{{#if this.ifParentCategory}}
<a class="parent-box-link" href={{@category.parentCategory.url}}>
{{#if this.ifParentProtected}}
{{icon this.lockIcon}}
{{/if}}
<h1>{{@category.parentCategory.name}}: </h1>
</a>
{{/if}}
{{#if this.ifProtected}}
{{icon this.lockIcon}}
{{/if}}
<h1>{{@category.name}}</h1>
</div>
<div class="category-title-description">
{{#if this.showCatDesc}}
<div class="cooked">
{{htmlSafe this.catDesc}}
{{#if this.inlineReadMore}}
<span class="category-about-url">
<a href={{@category.topic_url}}>{{this.aboutTopicUrl}}</a>
</span>
{{/if}}
</div>
{{/if}}
{{#if this.showFullCatDesc}}
<div class="cooked">
{{htmlSafe this.full_category_description}}
{{#if this.inlineReadMore}}
<span class="category-about-url">
<a href={{@category.topic_url}}>{{this.aboutTopicUrl}}</a>
</span>
{{/if}}
</div>
{{/if}}
</div>
</div>
{{#unless this.inlineReadMore}}
<div class="category-about-url">
<a href={{@category.topic_url}}>{{this.aboutTopicUrl}}</a>
</div>
{{/unless}}
</div>
{{/if}}
</template>
}
제안하신 디버깅을 시도해 보겠습니다. 그러면 몇 가지 결과가 나올지도 모릅니다.
수정: 의외네요. 컴포넌트를 주석 처리했는데도 여전히 그 오류가 발생합니다 , 하지만 템플릿에서 URL을 표시하는 것은 올바르게 표시됩니다.
david
(David Taylor)
10월 7, 2025, 9:16오전
4
이 부분이 의심스럽습니다. Ember 템플릿에서 괄호로 뭔가를 감싸면 헬퍼(즉, 함수)로 처리됩니다. 따라서 괄호를 한 단계 제거해야 할 것 같습니다:
- <div class="category-title-name" style={{if (not (this.logoImg))
+ <div class="category-title-name" style={{if (not this.logoImg)
참고로, 여기서는 프로덕션 인스턴스를 대상으로 개발하고 계신가요? 대신 개발 인스턴스를 사용하면 훨씬 더 자세한 오류 메시지를 받을 수 있습니다.
팁 감사합니다. 다른 브랜치에서는 정상적으로 작동하긴 합니다 , 하지만 그래도 그렇게 해볼게요. 프로덕션 환경에서 개발 환경으로 전환해 보겠습니다.
아, 그 변경을 한 뒤로 더 이상 오류가 없네요. 아마 그게 문제였나 봅니다. 도움 주셔서 감사합니다. <LightDarkImg />가 이제 잘 작동합니다!