87f02d3e by Michael Richards

Observe all intermediary keys in the keypath using the appropriate adapter. Deco…

…nstruct and recalculate the dirty remainder of the keypath when changed.
1 parent 6c10e1df
...@@ -57,10 +57,11 @@ Rivets.adapters['.'] = ...@@ -57,10 +57,11 @@ Rivets.adapters['.'] =
57 57
58 Object.defineProperty obj, keypath, 58 Object.defineProperty obj, keypath,
59 get: -> value 59 get: -> value
60 set: (newValue) -> 60 set: (newValue) =>
61 if newValue isnt value 61 if newValue isnt value
62 value = newValue 62 value = newValue
63 callback() for callback in callbacks[keypath] 63 callback() for callback in callbacks[keypath]
64 @observeMutations newValue, obj[@id], keypath
64 65
65 unless callback in callbacks[keypath] 66 unless callback in callbacks[keypath]
66 callbacks[keypath].push callback 67 callbacks[keypath].push callback
......
...@@ -8,6 +8,7 @@ class Rivets.Binding ...@@ -8,6 +8,7 @@ class Rivets.Binding
8 # keypath at which to listen for changes. 8 # keypath at which to listen for changes.
9 constructor: (@view, @el, @type, @keypath, @options = {}) -> 9 constructor: (@view, @el, @type, @keypath, @options = {}) ->
10 @formatters = @options.formatters || [] 10 @formatters = @options.formatters || []
11 @objectPath = []
11 @setBinder() 12 @setBinder()
12 @setModel() 13 @setModel()
13 14
...@@ -28,13 +29,32 @@ class Rivets.Binding ...@@ -28,13 +29,32 @@ class Rivets.Binding
28 interfaces = (k for k, v of @view.adapters) 29 interfaces = (k for k, v of @view.adapters)
29 tokens = Rivets.KeypathParser.parse @keypath, interfaces, '.' 30 tokens = Rivets.KeypathParser.parse @keypath, interfaces, '.'
30 31
31 @model = @view.models 32 @rootKey = tokens.shift()
32 @rootKey = tokens[0]
33 @key = tokens.pop() 33 @key = tokens.pop()
34 @objectPath ?= []
35
36 model = @view.adapters[@rootKey.interface].read @view.models, @rootKey.path
34 37
35 for token, index in tokens 38 for token, index in tokens
36 @model = @view.adapters[token.interface].read(@model, token.path) 39 current = @view.adapters[token.interface].read model, token.path
40
41 if @objectPath[index]?
42 if current isnt @objectPath[index]
43 @view.adapters[token.interface].unsubscribe model, token.path, @setModel
44 @view.adapters[token.interface].subscribe current, token.path, @setModel
45 else
46 @view.adapters[token.interface].subscribe model, token.path, @setModel
47
48 model = current
37 49
50 if @model and @model isnt model
51 @view.adapters[@key.interface].unsubscribe @model, @key.path, @sync
52 @view.adapters[@key.interface].subscribe model, @key.path, @sync
53 @model = model
54 @sync()
55 else
56 @model = model
57
38 # Applies all the current formatters to the supplied value and returns the 58 # Applies all the current formatters to the supplied value and returns the
39 # formatted value. 59 # formatted value.
40 formattedValue: (value) => 60 formattedValue: (value) =>
......