ddsgad
(DDSGadget)
2월 11, 2025, 9:38오후
1
DOMContentLoaded에서 실행되는 JS 함수가 있습니다: document.addEventListener(“DOMContentLoaded”, OURFUNCTION).
브라우저를 새로고침하면 잘 작동하지만, 사이트 내 페이지를 이동할 때는 절대 표시되지 않습니다. 이는 Discourse가 DOM을 한 번만 로드하고, 그 이후는 SPA처럼 클라이언트 사이드 네비게이션으로 처리하기 때문이라고 추정합니다. 그렇다면 Discourse 자체에서 네비게이션 변경 시 함수를 실행하려면 어떻게 해야 할까요? 예전에는 플러그인 API를 통해 이를 쉽게 할 수 있는 방법이 있었지만, 해당 API는 비추천(deprecated) 상태이며 더 이상 어떤 컴포넌트에서도 사용되고 있지 않습니다. 이걸 여전히 쉽게 할 수 있는 간단한 방법이 있을까요? 아니면 네비게이션 변경 시 일부 JavaScript를 실행하기 위해 컴포넌트를 통째로 만들어야 하나요? 감사합니다.
안녕하세요,
페이지 로드 시 발생하는 이벤트를 찾고 계신다면 api.onPageChange 를 사용할 수 있습니다.
api.onPageChange((url, title) => {
console.log('the page changed to: ' + url + ' and title ' + title);
});
다른 것을 찾고 계신다면, 달성하려는 내용을 좀 더 자세히 설명해 주시겠습니까? 그러면 더 정확한 답변을 드릴 수 있을 것입니다.
참고로, 도움이 될 수 있는 문서가 많이 준비되어 있습니다: Developer Guides - Discourse Meta .
음 … DOM 콘텐츠가 로드되었음을 보장하는지 확실하지 않아요. 라우트 변경 시점에 발화되는 것 같고, 이는 훨씬 이른 시점입니다.
DOM 로딩이 중요하다면, 컴포넌트를 플러그인 아웃렛에 연결하고 didInsert 수정자에서 발화하는 것을 고려해야 합니다.
라우트 변경만 중요하다면, onPageChange가 해결해 줄 수 있습니다.
말씀이 맞을 수도 있겠네요!
onPageChange는 다음 runloop에서 호출되므로, 대부분의 상황에서는 DOMContentLoaded 이후에 호출될 것으로 생각하지만, 이것이 보장된다고 단정할 수는 없습니다.
onPageChange에 의존하여 DOM 요소 관련 작업을 직접 수행하는 용례를 볼 수 있습니다. 참고로 routeDidChange 이벤트는 어디서 발화되는 건가요? (수정: ember에서 발화됩니다: ObjectProxy | 7.2.0 | Ember API Documentation )
didInsert 수정자에 대해서는 동의합니다. 정말 깔끔하네요!
ddsgad
(DDSGadget)
2월 11, 2025, 10:55오후
5
감사합니다. 문서를 꼼꼼히 읽어봤고, 제 코멘트와 디스커스(Discourse) 멤버의 후속 답변에 따르면 플러그인 API는 레거시이며 곧 비추천(deprecated) 처리될 예정이라고 합니다. 따라서 현재는 동작할 수 있지만, 향후 업데이트에서 깨질 가능성이 높다고 생각합니다. 그래서 더 나은 솔루션을 찾고 있습니다. 이 정도 기능을 위해 글리머(Glimmer) 컴포넌트를 만드는 것은 과한 것 같아, 다른 이벤트를 활용할 수 있지 않을까 해서 문의드립니다.
그것이 정확하지 않다고 생각합니다.
Discourse’s JavaScript API allows themes and plugins to make extensive customizations to the user experience. The simplest way to use it is to create a new theme from the admin panel, click “Edit Code”, and then head to the JS tab.
For file-based themes, the API can be used by creating a file in the api-initializers directory. For theme’s that’s {theme}/javascripts/api-initializers/init-theme.gjs, and for plugins, it’s {plugin}/assets/javascripts/discourse/api-initializers/init-plugin.js. The c…
이 링크는 지난주에 업데이트되었습니다.
비추천(deprecated)된 항목은 다음과 같습니다:
위젯 API
Raw 템플릿
일반적인 템플릿 오버라이딩
ddsgad
(DDSGadget)
2월 11, 2025, 11:25오후
7
정리해 주셔서 감사합니다! 그래서 위젯 API만 해당되는 거군요. 그럼 먼저 위에 제시된 API 제안들을 시도해 보겠습니다.
DDSGadget:
위젯 API일 뿐이에요
이건 오히려 축복이죠 , Glimmer은 개발자에게 훨씬 더 친화적이니까요
ddsgad
(DDSGadget)
2월 12, 2025, 7:26오후
9
참고로, api.OnPageChange로 테스트해 봤는데 정상적으로 작동합니다. 아직까지 OnPageChange를 호출할 때 DOM 콘텐츠가 사용 불가능한 경우는 한 번도 겪어 본 적이 없기 때문에, DomContentLoaded 이후에 발화되는 것으로 보입니다. 다만 100% 확신은 못 하겠습니다. 이 문제에 대해 도움을 주셔서 감사합니다.
좋습니다. 다만 타이밍이 보장되지는 않는다는 점에 유의하세요. 하지만 사용 사례에 맞게 작동하게 되어 기쁩니다!
ddsgad
(DDSGadget)
2월 21, 2025, 3:00오후
11
이것이 무엇을 의미하는지 좀 더 자세히 설명해 주실 수 있을까요? didInsert 수정자란 무엇인가요? 저는 decorateCookedElement에서 발동시키고 있습니다. 감사합니다.
로버트가 지적했듯이, 문서가 가장 좋은 방법입니다. 레포지토리에서도 수많은 예제를 확인할 수 있습니다: Code search results · GitHub
ddsgad
(DDSGadget)
2월 21, 2025, 3:03오후
15
DDSGadget:
didInsert 수정자(modifier)
아, 알겠습니다. 그러면 이건 ember 기능이고 discourse와는 관련이 없군요? 코드에서 실제로 "discourse"와 관련이 있는 부분은 pluginoutlet뿐이겠네요?
네, Glimmer 표준의 일부입니다.
pluginOutlets는 다른 Components를 마운트하도록 설계된 특별한 Components입니다:
With the contents:
```handlebars
<b>Hello World</b>
```
Will insert <b>Hello World</b> at that point in the template.
**/
export default class PluginOutletComponent extends GlimmerComponentWithDeprecatedParentView {
@service clientErrorHandler;
context = {
...helperContext(),
get parentView() {
return this.parentView;
},
get() {
deprecated(GET_DEPRECATION_MSG, {
id: "discourse.plugin-outlet-context-get",
});