29f7ffa2 by Michael Richards

Merge pull request #43 from mikeric/dependant-attributes-for-computed-properties

Computed properties
2 parents c368733e 71bab2f6
...@@ -26,7 +26,7 @@ describe('Rivets.Binding', function() { ...@@ -26,7 +26,7 @@ describe('Rivets.Binding', function() {
26 it('subscribes to the model for changes via the adapter', function() { 26 it('subscribes to the model for changes via the adapter', function() {
27 spyOn(rivets.config.adapter, 'subscribe'); 27 spyOn(rivets.config.adapter, 'subscribe');
28 binding.bind(); 28 binding.bind();
29 expect(rivets.config.adapter.subscribe).toHaveBeenCalled(); 29 expect(rivets.config.adapter.subscribe).toHaveBeenCalledWith(model, 'name', binding.set);
30 }); 30 });
31 31
32 describe('with preloadData set to true', function() { 32 describe('with preloadData set to true', function() {
...@@ -38,8 +38,8 @@ describe('Rivets.Binding', function() { ...@@ -38,8 +38,8 @@ describe('Rivets.Binding', function() {
38 spyOn(binding, 'set'); 38 spyOn(binding, 'set');
39 spyOn(rivets.config.adapter, 'read'); 39 spyOn(rivets.config.adapter, 'read');
40 binding.bind(); 40 binding.bind();
41 expect(rivets.config.adapter.read).toHaveBeenCalledWith(model, 'name');
41 expect(binding.set).toHaveBeenCalled(); 42 expect(binding.set).toHaveBeenCalled();
42 expect(rivets.config.adapter.read).toHaveBeenCalled();
43 }); 43 });
44 }); 44 });
45 45
...@@ -55,6 +55,19 @@ describe('Rivets.Binding', function() { ...@@ -55,6 +55,19 @@ describe('Rivets.Binding', function() {
55 expect(binding.set).toHaveBeenCalledWith('espresso'); 55 expect(binding.set).toHaveBeenCalledWith('espresso');
56 }); 56 });
57 }); 57 });
58
59 describe('with dependencies', function() {
60 beforeEach(function() {
61 binding.options.dependencies = ['fname', 'lname'];
62 });
63
64 it('sets up observers on the dependant attributes', function() {
65 spyOn(rivets.config.adapter, 'subscribe');
66 binding.bind();
67 expect(rivets.config.adapter.subscribe).toHaveBeenCalledWith(model, 'fname', binding.dependencyCallbacks['fname']);
68 expect(rivets.config.adapter.subscribe).toHaveBeenCalledWith(model, 'lname', binding.dependencyCallbacks['lname']);
69 });
70 });
58 }); 71 });
59 72
60 describe('set()', function() { 73 describe('set()', function() {
......
...@@ -63,6 +63,18 @@ class Rivets.Binding ...@@ -63,6 +63,18 @@ class Rivets.Binding
63 if Rivets.config.preloadData 63 if Rivets.config.preloadData
64 @set Rivets.config.adapter.read @model, @keypath 64 @set Rivets.config.adapter.read @model, @keypath
65 65
66 if @options.dependencies?.length
67 @dependencyCallbacks = {}
68
69 for keypath in @options.dependencies
70 callback = @dependencyCallbacks[keypath] = (value) =>
71 @set if @options.bypass
72 @model[@keypath]
73 else
74 Rivets.config.adapter.read @model, @keypath
75
76 Rivets.config.adapter.subscribe @model, keypath, callback
77
66 if @type in @bidirectionals 78 if @type in @bidirectionals
67 bindEvent @el, 'change', @publish 79 bindEvent @el, 'change', @publish
68 80
...@@ -75,6 +87,11 @@ class Rivets.Binding ...@@ -75,6 +87,11 @@ class Rivets.Binding
75 unbind: => 87 unbind: =>
76 Rivets.config.adapter.unsubscribe @model, @keypath, @set 88 Rivets.config.adapter.unsubscribe @model, @keypath, @set
77 89
90 if @options.dependencies?.length
91 for keypath in @options.dependencies
92 callback = @dependencyCallbacks[keypath]
93 Rivets.config.adapter.unsubscribe @model, keypath, callback
94
78 if @type in @bidirectionals 95 if @type in @bidirectionals
79 @el.removeEventListener 'change', @publish 96 @el.removeEventListener 'change', @publish
80 97
...@@ -104,12 +121,16 @@ class Rivets.View ...@@ -104,12 +121,16 @@ class Rivets.View
104 121
105 type = attribute.name.replace bindingRegExp, '' 122 type = attribute.name.replace bindingRegExp, ''
106 pipes = (pipe.trim() for pipe in attribute.value.split '|') 123 pipes = (pipe.trim() for pipe in attribute.value.split '|')
107 path = pipes.shift().split(/(\.|:)/) 124 context = (ctx.trim() for ctx in pipes.shift().split '>')
125 path = context.shift().split /(\.|:)/
108 options.formatters = pipes 126 options.formatters = pipes
109 model = @models[path.shift()] 127 model = @models[path.shift()]
110 options.bypass = path.shift() is ':' 128 options.bypass = path.shift() is ':'
111 keypath = path.join() 129 keypath = path.join()
112 130
131 if dependencies = context.shift()
132 options.dependencies = dependencies.split /\s+/
133
113 if eventRegExp.test type 134 if eventRegExp.test type
114 type = type.replace eventRegExp, '' 135 type = type.replace eventRegExp, ''
115 options.special = "event" 136 options.special = "event"
......