Browse Source

Merge pull request #2469 from ellisonbg/vdom-no-model

Allow `VDomRenderer` to work with `null` model
Steven Silvester 7 years ago
parent
commit
1b3ca72408
2 changed files with 33 additions and 1 deletions
  1. 9 1
      packages/apputils/src/vdom.ts
  2. 24 0
      test/src/apputils/vdom.spec.ts

+ 9 - 1
packages/apputils/src/vdom.ts

@@ -26,7 +26,7 @@ import {
  * Phosphor widget that encodes best practices for VDOM based rendering.
  */
 export
-abstract class VDomRenderer<T extends VDomRenderer.IModel> extends Widget {
+abstract class VDomRenderer<T extends VDomRenderer.IModel | null> extends Widget {
   /**
    * A signal emited when the model changes.
    */
@@ -80,6 +80,14 @@ abstract class VDomRenderer<T extends VDomRenderer.IModel> extends Widget {
     VirtualDOM.render(vnode, this.node);
   }
 
+  /* Called after the widget is attached to the DOM
+   * 
+   * Make sure the widget is rendered, even if the model has not changed.
+   */
+  protected onAfterAttach(msg: Message): void {
+    this.update();
+  }
+
   /**
    * Render the content of this widget using the virtial DOM.
    *

+ 24 - 0
test/src/apputils/vdom.spec.ts

@@ -9,6 +9,10 @@ import {
   h, VirtualNode
 } from '@phosphor/virtualdom';
 
+import {
+  Widget
+} from '@phosphor/widgets'
+
 import {
   VDomModel, VDomRenderer
 } from '@jupyterlab/apputils';
@@ -33,6 +37,12 @@ class TestWidget extends VDomRenderer<TestModel> {
   }
 }
 
+class TestWidgetNoModel extends VDomRenderer<null> {
+  protected render(): VirtualNode {
+    return h.span("No model!");
+  }
+}
+
 
 describe('@jupyterlab/domutils', () => {
 
@@ -116,6 +126,20 @@ describe('@jupyterlab/domutils', () => {
 
     });
 
+    describe('#noModel()', () => {
+
+      it('should work with a null model', (done) => {
+        let widget = new TestWidgetNoModel();
+        Widget.attach(widget, document.body);
+        requestAnimationFrame(() => {
+          let span = widget.node.firstChild as HTMLElement;
+          expect(span.textContent).to.equal('No model!');
+          done();
+        });
+      })
+
+    })
+
   });
 
 });