Add support for constant-text expressions. This new advanced parser
activates when it detects {{}} in the attribute value. This can be useful when building up values with variables interspersed with constants. An example is href="/path/to/images/{{order.orderId}}/{{order.overlay}}.png" This correctly handles bind/unbind, and updates to the possibly many internal variables.
Showing
1 changed file
with
47 additions
and
0 deletions
... | @@ -117,7 +117,54 @@ loopDeps = (binder, callback) -> | ... | @@ -117,7 +117,54 @@ loopDeps = (binder, callback) -> |
117 | 117 | ||
118 | callback model, keypath | 118 | callback model, keypath |
119 | 119 | ||
120 | expressionRegex = /(.*?)\{\{([^{}]+)\}\}/ | ||
121 | |||
122 | createSubExpressionBinder = (outerBinding, values, i) -> | ||
123 | values[i] = null | ||
124 | routine: (el, value) -> | ||
125 | values[i] = value | ||
126 | outerBinding.sync() | ||
127 | |||
120 | defaultExpressionParser = (view, node, type, models, value) -> | 128 | defaultExpressionParser = (view, node, type, models, value) -> |
129 | if expressionRegex.test value | ||
130 | binding = new Rivets.Binding node, type, models | ||
131 | |||
132 | values = [] | ||
133 | subs = [] | ||
134 | while value && expressionRegex.test value | ||
135 | matches = expressionRegex.exec value | ||
136 | value = value.substring matches[0].length | ||
137 | values[values.length] = matches[1] if matches[1] | ||
138 | subs[subs.length] = subBinding = defaultExpressionParser view, null, '*', models, matches[2] | ||
139 | subBinding.binder = createSubExpressionBinder binding, values, values.length | ||
140 | values[values.length] = value if value | ||
141 | bindMethod = binding.bind | ||
142 | unbindMethod = binding.unbind | ||
143 | binding.sync = -> | ||
144 | binding.set values.join '' | ||
145 | |||
146 | # Publishes the value currently set on the input element back to the model. | ||
147 | binding.publish = -> | ||
148 | # can't really do anything with this | ||
149 | |||
150 | # Subscribes to the model for changes at the specified keypath. Bi-directional | ||
151 | # routines will also listen for changes on the element to propagate them back | ||
152 | # to the model. | ||
153 | binding.bind = -> | ||
154 | bindMethod() | ||
155 | |||
156 | for sub in subs | ||
157 | sub.bind() | ||
158 | |||
159 | # Unsubscribes from the model and the element. | ||
160 | binding.unbind = -> | ||
161 | unbindMethod() | ||
162 | |||
163 | for sub in subs | ||
164 | sub.unbind() | ||
165 | |||
166 | return binding | ||
167 | |||
121 | pipes = (pipe.trim() for pipe in value.split '|') | 168 | pipes = (pipe.trim() for pipe in value.split '|') |
122 | context = (ctx.trim() for ctx in pipes.shift().split '<') | 169 | context = (ctx.trim() for ctx in pipes.shift().split '<') |
123 | path = context.shift() | 170 | path = context.shift() | ... | ... |
-
Please register or sign in to post a comment