Pārlūkot izejas kodu

Make the model set-once

Steven Silvester 9 gadi atpakaļ
vecāks
revīzija
683784e5be

+ 17 - 25
src/notebook/output-area/widget.ts

@@ -122,43 +122,34 @@ class OutputAreaWidget extends Widget {
     this.layout = new PanelLayout();
   }
 
-  /**
-   * A signal emitted when the widget's model changes.
-   */
-  get modelChanged(): ISignal<OutputAreaWidget, void> {
-     return Private.modelChangedSignal.bind(this);
-  }
-
   /**
    * The model for the widget.
+   *
+   * #### Notes
+   * The model is single-use only. It cannot be set to `null` and it
+   * cannot be changed after the first assignment.
+   *
+   * The model is disposed automatically when the widget is disposed.
    */
   get model(): OutputAreaModel {
     return this._model;
   }
-  set model(newValue: OutputAreaModel) {
-    if (!newValue && !this._model || newValue === this._model) {
+  set model(value: OutputAreaModel) {
+    value = value || null;
+    if (this._model === value) {
       return;
     }
-
-    // TODO: Reuse widgets if possible.
     if (this._model) {
-      this._model.clear();
-      this._model.changed.disconnect(this._onModelChanged, this);
+      throw new Error('Cannot change widget model.');
     }
 
-    this._model = newValue;
-
-    this.modelChanged.emit(void 0);
-
-    if (!newValue) {
-      return;
-    }
-
-    for (let i = 0; i < newValue.length; i++) {
-      let widget = this._createOutput(newValue.get(i));
-      (this.layout as PanelLayout).addChild(widget);
+    this._model = value;
+    let layout = this.layout as PanelLayout;
+    for (let i = 0; i < value.length; i++) {
+      let widget = this._createOutput(value.get(i));
+      layout.addChild(widget);
     }
-    newValue.changed.connect(this._onModelChanged, this);
+    value.changed.connect(this._onModelChanged, this);
   }
 
   /**
@@ -242,6 +233,7 @@ class OutputAreaWidget extends Widget {
     if (this.isDisposed) {
       return;
     }
+    this._model.dispose();
     this._model = null;
     this._rendermime = null;
     this._renderer = null;

+ 12 - 29
test/src/notebook/output-area/widget.spec.ts

@@ -83,22 +83,6 @@ describe('notebook/output-area/widget', () => {
 
     });
 
-    describe('#modelChanged', () => {
-
-      it('should be emitted when the model of the widget changes', () => {
-        let widget = new OutputAreaWidget({ rendermime });
-        let called = false;
-        widget.modelChanged.connect((sender, args) => {
-          expect(sender).to.be(widget);
-          expect(args).to.be(void 0);
-          called = true;
-        });
-        widget.model = new OutputAreaModel();
-        expect(called).to.be(true);
-      });
-
-    });
-
     describe('#model', () => {
 
       it('should default to `null`', () => {
@@ -113,27 +97,24 @@ describe('notebook/output-area/widget', () => {
         expect(widget.model).to.be(model);
       });
 
-      it('should emit `modelChanged` when the model changes', () => {
-        let widget = new OutputAreaWidget({ rendermime });
-        let called = false;
-        widget.modelChanged.connect(() => { called = true; });
-        widget.model = new OutputAreaModel();
-        expect(called).to.be(true);
+      it('should create widgets for the model items', () => {
+        let widget = createWidget();
+        expect(widget.childCount()).to.be(5);
       });
 
-      it('should not emit `modelChanged` when the model does not change', () => {
+      it('should be a no-op if set to the same value', () => {
         let widget = new OutputAreaWidget({ rendermime });
-        let called = false;
         let model = new OutputAreaModel();
         widget.model = model;
-        widget.modelChanged.connect(() => { called = true; });
         widget.model = model;
-        expect(called).to.be(false);
+        expect(widget.model).to.be(model);
       });
 
-      it('should create widgets for the model items', () => {
-        let widget = createWidget();
-        expect(widget.childCount()).to.be(5);
+      it('should be write-once', () => {
+        let widget = new OutputAreaWidget({ rendermime });
+        let model = new OutputAreaModel();
+        widget.model = model;
+        expect(() => { widget.model = new OutputAreaModel(); }).to.throwError();
       });
 
       it('should add the `jp-OutputArea-output` class to the child widgets', () => {
@@ -264,7 +245,9 @@ describe('notebook/output-area/widget', () => {
 
       it('should dispose of the resources held by the widget', () => {
         let widget = createWidget();
+        let model = widget.model;
         widget.dispose();
+        expect(model.isDisposed).to.be(true);
         expect(widget.model).to.be(null);
         expect(widget.rendermime).to.be(null);
         expect(widget.renderer).to.be(null);