Use view providers to build views if a matching provider is available

This commit is contained in:
Nathan Sobo 2014-09-17 10:58:46 -06:00
parent 54378b11d4
commit b5499247b3
2 changed files with 35 additions and 0 deletions

View File

@ -24,6 +24,30 @@ describe "ViewRegistry", ->
expect(node.__spacePenView).toBe view
describe "when passed a model object", ->
describe "when a view provider is registered matching the object's constructor", ->
it "constructs a view element and assigns the model on it", ->
class TestModel
class TestModelSubclass extends TestModel
class TestView
setModel: (@model) ->
model = new TestModel
registry.addViewProvider
modelClass: TestModel
viewClass: TestView
view = registry.getView(model)
expect(view instanceof TestView).toBe true
expect(view.model).toBe model
subclassModel = new TestModelSubclass
view2 = registry.getView(subclassModel)
expect(view2 instanceof TestView).toBe true
expect(view2.model).toBe subclassModel
describe "when no view provider is registered for the object's constructor", ->
describe "when the object has a .getViewClass() method", ->
it "builds an instance of the view class with the model, then returns its root node with a __spacePenView property pointing at the view", ->

View File

@ -4,6 +4,10 @@ module.exports =
class ViewRegistry
constructor: ->
@views = new WeakMap
@providers = []
addViewProvider: (provider) ->
@providers.push(provider)
getView: (object) ->
return unless object?
@ -21,9 +25,16 @@ class ViewRegistry
else if object instanceof jQuery
object[0].__spacePenView ?= object
object[0]
else if provider = @findProvider(object)
element = new provider.viewClass
element.setModel(object)
element
else if viewClass = object?.getViewClass?()
view = new viewClass(object)
view[0].__spacePenView ?= view
view[0]
else
throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.")
findProvider: (object) ->
@providers.find ({modelClass}) -> object instanceof modelClass