# Ein Widget neu laden/aktualisieren, wenn ein anderes Widget aktualisiert wird

**URL:** https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356
**Category:** Development
**Created:** [24. September 2021 um 06:16 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356 "2021-09-24T06:16:46Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![saurabhmasc](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@saurabhmasc](https://meta.discourse.org/u/saurabhmasc)
#### Post date: [24. September 2021 um 06:16 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/1 "2021-09-24T06:16:47Z")

</div>

Hallo zusammen,

wir haben ein Widget namens „topic-timeline-bookmark" erstellt, das den Lesezeichen-Button auf Themen-Ebene nach dem Widget „topic-timeline" anzeigt.

 ![image](https://global.discourse-cdn.com/meta/original/3X/4/b/4b988d1b7603d2dbbdea5e444e0a4600b98f9397.png)

Wenn wir nun auf den Lesezeichen-Button von _ **topic-timeline** _ klicken, wird das Modal-Fenster zum Festlegen des Lesezeichens angezeigt. Beim Speichern des Lesezeichens werden die Lesezeichen-Buttons unter den _ **first-post-menu** _-Buttons und den _ **topic-footer-button** _ aktualisiert, aber der Button von _ **topic-timeline** _ selbst wird nicht aktualisiert, bis das Widget _ **topic-timeline** _ neu geladen wird (d. h. bis wir scrollen), und umgekehrt.

### first-post-menu

![image](https://global.discourse-cdn.com/meta/original/3X/6/3/630140d08aede405680568aa64a19df38940623c.png)

* * *

### topic-footer-button

![image](https://global.discourse-cdn.com/meta/original/3X/f/9/f90ab85e13915de396501c07977b7ad0758f7358.png)

Ich habe festgestellt, dass das Widget _ **post-stream** _ immer dann neu geladen wird, wenn ein Lesezeichen gesetzt oder entfernt wird. Daher funktionieren die Lesezeichen-Buttons im Post-Menü und im topic-footer-button synchron.

> <https://github.com/discourse/discourse/blob/57f17854fb93e2d88c7b4eddc040338530c98239/app/assets/javascripts/discourse/app/controllers/topic.js#L755>

Wie kann ich nun mein Widget „topic-timeline-bookmark" immer dann neu laden, wenn ein Lesezeichen gesetzt oder entfernt wird oder wenn das Widget _ **post-stream** _ neu geladen wird? Hier ist mein Code:

```plaintext
<script type="text/discourse-plugin" version="0.8">
  const { h } = require('virtual-dom');
  const { getOwner } = require("discourse-common/lib/get-owner");
  const topicController = getOwner(this).lookup("controller:topic");

  api.createWidget("topic-timeline-bookmark", {  
      tagName: 'div.discourse-bookmark-button-wrapper',
      buildKey: () => `topic-timeline-bookmark`,
      toggleBookmark() {
        topicController.send('toggleBookmark');
      },
      html(attrs, state) { 
        let contents = [];
        const user = api.getCurrentUser();
        if (user) {
            let tooltip = 'bookmarked.help.bookmark';
            let label = 'bookmarked.title';
            let buttonClass = 'btn btn-default bookmark';
            let icon = "bookmark";  
            let bookmarkedPosts = topicController.model.bookmarked_posts;
            let bookmarkCount = 0;

            if(bookmarkedPosts && bookmarkedPosts.length > 0){
              bookmarkCount = bookmarkedPosts.length;
              
              //Icon
              if (bookmarkedPosts.some((bookmark) => bookmark.reminder_at))
                icon = "discourse-bookmark-clock";
              else
                icon = "bookmark";

              //Label
              if (bookmarkCount === 0)               
                  label = "bookmarked.title";          
              else if (bookmarkCount === 1)
                  label = "bookmarked.edit_bookmark"; 
              else 
                  label = "bookmarked.clear_bookmarks";

              //Tooltip
              if (bookmarkedPosts.length === 1)
                  tooltip = 'bookmarked.help.edit_bookmark';
              else if (bookmarkedPosts.find((x) => x.reminder_at))
                  tooltip = 'bookmarked.help.unbookmark_with_reminder';
              
              //Append CSS class if bookmark is set
              if (bookmarkCount > 0) { buttonClass += ' bookmarked' }
            }
    
            contents.push(
            this.attach('button', {
              action: 'toggleBookmark',
              title: tooltip,
              label: label,
              icon: icon,
              className: buttonClass
            })
          );
        }
        return contents;
      }, 
    });
 
  api.decorateWidget('topic-timeline:after', function(helper) {
    return helper.attach('topic-timeline-bookmark');
  });
</script>

```

---

<div class="post-metadata">

### Author: ![jordan.vidrine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jordan.vidrine/32/515563_2.png) [@jordan.vidrine](https://meta.discourse.org/u/jordan.vidrine)
#### Post date: [28. September 2021 um 14:11 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/5 "2021-09-28T14:11:47Z")

</div>

Vielen Dank, dass Sie sich gemeldet haben. Einer unserer Entwickler wird sich dies ansehen und mit hilfreichen Informationen zurückmelden.

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [28. September 2021 um 16:35 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/7 "2021-09-28T16:35:50Z")

</div>

Hallo,

ich habe es lokal noch nicht ausprobiert, aber folgender Ansatz könnte funktionieren:

Füge in deinem Hauptskript diesen API-Aufruf hinzu:

```javascript
api.dispatchWidgetAppEvent('topic-timeline-bookmark', 'force-refresh', 'post-stream:refresh');

```

In deinem Widget-Code deklariere diese Funktion:

```javascript
api.createWidget("topic-timeline-bookmark", {  
  // Code weggelassen

  // Möglicherweise könnte man es direkt im API-Aufruf statt 'force-refresh'
  // 'schedule-rerender' nennen und diese Funktion somit vermeiden
  forceRefresh() {
    this.scheduleRerender();
  }
});

```

Ich denke, das sollte funktionieren. Falls nicht, lass es mich bitte wissen, dann versuche ich, lokal ein funktionierendes Beispiel zu erstellen.

---

<div class="post-metadata">

### Author: ![saurabhmasc](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@saurabhmasc](https://meta.discourse.org/u/saurabhmasc)
#### Post date: [29. September 2021 um 06:08 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/8 "2021-09-29T06:08:39Z")

</div>

Vielen Dank für deine Antwort, @joffreyjaffeux.

Wir haben den von dir vorgeschlagenen Code ausprobiert, aber er funktioniert nicht.

1. Wir haben den folgenden API-Aufruf hinzugefügt:  
`api.dispatchWidgetAppEvent('topic-timeline-bookmark', 'force-refresh', 'post-stream:refresh');`  
Und danach die Methode `forceRefresh()` im Widget „topic-timeline-bookmark" hinzugefügt.  
Das funktioniert jedoch nicht.

2. Ich habe auch versucht, den zweiten Parameter der `dispatchWidgetAppEvent`-Methode in „schedule-rerender" umzubenennen und die `forceRefresh`-Funktion aus dem Widget zu entfernen. Auch das funktioniert nicht.

Ich habe mir die Implementierung der `api.dispatchWidgetAppEvent`-Methode angesehen. Sie nimmt drei Argumente entgegen, wobei das zweite der **widgetKey** ist. Ich denke, dies sollte der Wert sein, der von der `buildKey()`-Funktion des Widgets zurückgegeben wird.  
Das dritte Argument ist das **appEvent** , das in camelCase umgewandelt und als Methodenname für uns verwendet wird.

[https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/lib/plugin-api.js#L1448](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/lib/plugin-api.js#L1448)

Übersehen wir etwas?

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [29. September 2021 um 06:12 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/9 "2021-09-29T06:12:44Z")

</div>

Ich werde es lokal versuchen, ich habe wahrscheinlich einen Fehler gemacht.

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [29. September 2021 um 14:59 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/11 "2021-09-29T14:59:06Z")

</div>

@saurabhmasc Ich habe es lokal zum Laufen gebracht, musste jedoch einen Fehler im Core beheben und eine neue Funktion im Core hinzufügen. Ich werde das Thema aktualisieren, sobald alles zusammengeführt ist.

---

<div class="post-metadata">

### Author: ![saurabhmasc](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@saurabhmasc](https://meta.discourse.org/u/saurabhmasc)
#### Post date: [29. September 2021 um 15:02 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/12 "2021-09-29T15:02:33Z")

</div>

Danke, @j.jaffeux.

---

<div class="post-metadata">

### Author: ![saurabhmasc](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@saurabhmasc](https://meta.discourse.org/u/saurabhmasc)
#### Post date: [6. Oktober 2021 um 06:32 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/13 "2021-10-06T06:32:01Z")

</div>

Hallo @j.jaffeux,

> [@j.jaffeux](#):
>
> Ich habe es lokal zum Laufen gebracht, musste jedoch einen Fehler im Kern beheben und eine neue Funktion im Kern hinzufügen. Ich werde das Thema aktualisieren, sobald alles zusammengeführt ist.

Hast du eine Ahnung, wann diese Änderungen zusammengeführt werden?

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [6. Oktober 2021 um 09:55 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/14 "2021-10-06T09:55:14Z")

</div>

Hallo, ja, ich habe es gerade zusammengeführt (du musst es also zuerst bereitstellen): [DEV: adds a topic level bookmark toggle (#14471) · discourse/discourse@20e70d0 · GitHub](https://github.com/discourse/discourse/commit/20e70d0ac5febfeee6c6cc0a83881a79422bba57)

Außerdem ist dies eine Beispielkomponente, die ich dafür erstellt habe:

> **[GitHub - jjaffeux/bookmark-timeline: Adds a bookmark button under the timeline](https://github.com/jjaffeux/bookmark-timeline)**
>
> Adds a bookmark button under the timeline

Lass mich wissen, falls du Fragen hast.

---

<div class="post-metadata">

### Author: ![saurabhmasc](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@saurabhmasc](https://meta.discourse.org/u/saurabhmasc)
#### Post date: [6. Oktober 2021 um 12:40 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/15 "2021-10-06T12:40:13Z")

</div>

Hallo @j.jaffeux,

1. Wir haben festgestellt, dass früher, wenn wir über die Topic-Footer-Buttons ein Lesezeichen gesetzt haben, auch der erste Beitrag als gelistet markiert wurde. Jetzt wird der erste Beitrag jedoch nicht mehr gelistet. Ist das jetzt korrekt?  

2. Wir haben Ihre Komponente in allen Fällen getestet und sie funktioniert einwandfrei. Lediglich die Funktion „Lesezeichen löschen“ arbeitet nicht synchron.  
Um dies zu beheben, haben wir folgende Codezeilen hinzugefügt, und jetzt funktioniert die Funktion „Lesezeichen löschen“ ebenfalls einwandfrei:

```plaintext
  api.dispatchWidgetAppEvent(
    "topic-timeline",
    "topic-timeline-bookmark",
    "post-stream:refresh"
  );

```

Vielen Dank.

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [6. Oktober 2021 um 12:48 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/16 "2021-10-06T12:48:27Z")

</div>

Ich werde den ersten Punkt prüfen. Was den zweiten betrifft: Ja, es ist möglich, dass ich einen Fall übersehen habe. Der Hauptautor der Lesezeichen ist derzeit abwesend, und ich möchte ein paar Dinge ändern, aber dafür muss er zurück sein. Deine Korrektur sollte in Ordnung sein.

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [7. Oktober 2021 um 09:30 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/17 "2021-10-07T09:30:54Z")

</div>

> [@saurabhmasc](#):
>
> Wir haben festgestellt, dass früher, wenn wir über die Topic-Footer-Buttons ein Lesezeichen gesetzt haben, auch der erste Beitrag als gelistet markiert wurde. Jetzt wird der erste Beitrag jedoch nicht mehr gelistet. Ist das nun korrekt?

Nach verschiedenen Tests denke ich, dass dies das erwartete Verhalten ist (und nicht mit der Komponente zusammenhängt).

---

<div class="post-metadata">

### Author: ![saurabhmasc](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@saurabhmasc](https://meta.discourse.org/u/saurabhmasc)
#### Post date: [7. Oktober 2021 um 12:57 UTC](https://meta.discourse.org/t/reload-refresh-a-widget-on-refresh-of-another-widget/204356/18 "2021-10-07T12:57:47Z")

</div>

Danke für dein Feedback, @j.jaffeux.

> [@j.jaffeux](#):
>
> Ja, ich habe es gerade zusammengeführt (du musst es also zuerst bereitstellen): [DEV: fügt einen Lesezeichen-Umschalter auf Themenebene hinzu (#14471) · discourse/discourse@20e70d0 · GitHub](https://github.com/discourse/discourse/commit/20e70d0ac5febfeee6c6cc0a83881a79422bba57)

Wir werden ein neues Ticket erstellen und bitten, diese Kernänderungen in unsere Staging- und Produktionsumgebungen zu übernehmen, damit wir sie in Staging testen können.
