|
167 | 167 | return this.object_ = f.apply(null, argumentValues); |
168 | 168 | }, |
169 | 169 |
|
170 | | - toDOM: function(fn) { |
171 | | - var object = this.object; |
172 | | - return function(values) { |
173 | | - var value = fn(values); |
174 | | - return object.toDOM(value); |
175 | | - }; |
| 170 | + toDOM: function(value) { |
| 171 | + return this.object.toDOM(value); |
176 | 172 | }, |
177 | 173 |
|
178 | 174 | toModel: function(value) { |
|
344 | 340 | if (!delegate.expression && !delegate.labeledStatements.length) |
345 | 341 | throw Error('No expression or labelled statements found.'); |
346 | 342 |
|
347 | | - // TODO(rafaelw): This is a bit of hack. We'd like to support syntax for |
348 | | - // binding to class like class="{{ foo: bar; baz: bat }}", so we're |
349 | | - // abusing ECMAScript labelled statements for this use. The main downside |
350 | | - // is that ECMAScript indentifiers are more limited than CSS classnames. |
351 | 343 | this.expression = delegate.expression; |
| 344 | + getFn(this.expression); // forces enumeration of path dependencies |
352 | 345 |
|
353 | | - var resolveFn = delegate.labeledStatements.length ? |
354 | | - newLabeledResolve(delegate.labeledStatements) : |
355 | | - getFn(delegate.expression); |
356 | | - |
357 | | - delegate.filters.forEach(function(filter) { |
358 | | - resolveFn = filter.toDOM(resolveFn); |
359 | | - }); |
360 | | - |
361 | | - this.resolveFn = resolveFn; |
362 | 346 | this.paths = delegate.depsList; |
363 | 347 | this.filters = delegate.filters; |
| 348 | + |
| 349 | + // TODO(rafaelw): This is a bit of hack. We'd like to support syntax for |
| 350 | + // binding to class like class="{{ foo: bar; baz: bat }}", so we're |
| 351 | + // abusing ECMAScript labelled statements for this use. The main downside |
| 352 | + // is that ECMAScript indentifiers are more limited than CSS classnames. |
| 353 | + if (delegate.labeledStatements.length) |
| 354 | + this.expression = newLabeledResolve(delegate.labeledStatements); |
364 | 355 | } |
365 | 356 |
|
366 | 357 | Expression.prototype = { |
367 | 358 | getBinding: function(model) { |
368 | 359 | var paths = this.paths; |
369 | 360 | if (!paths.length) |
370 | | - return { value: this.resolveFn({}) }; // only literals in expression. |
| 361 | + return { value: this.getValue() }; // only literals in expression. |
371 | 362 |
|
372 | 363 | var self = this; |
| 364 | + var valueFn = function(values) { |
| 365 | + return self.getValue(values); |
| 366 | + }; |
| 367 | + |
373 | 368 | var setValueFn = function(newValue) { |
374 | 369 | var values; |
375 | 370 | if (self.paths.length == 1) { |
|
384 | 379 | }; |
385 | 380 |
|
386 | 381 | if (paths.length === 1) { |
387 | | - return new PathObserver(model, paths[0], undefined, undefined, |
388 | | - this.resolveFn, |
| 382 | + return new PathObserver(model, paths[0], undefined, undefined, valueFn, |
389 | 383 | setValueFn); |
390 | 384 | } |
391 | 385 |
|
392 | | - var binding = new CompoundPathObserver(undefined, undefined, |
393 | | - this.resolveFn, |
| 386 | + var binding = new CompoundPathObserver(undefined, undefined, valueFn, |
394 | 387 | setValueFn); |
395 | 388 |
|
396 | 389 | for (var i = 0; i < paths.length; i++) { |
|
401 | 394 | return binding; |
402 | 395 | }, |
403 | 396 |
|
| 397 | + getValue: function(depsValues) { |
| 398 | + var value = getFn(this.expression)(depsValues); |
| 399 | + for (var i = 0; i < this.filters.length; i++) |
| 400 | + value = this.filters[i].toDOM(value); |
| 401 | + return value; |
| 402 | + }, |
| 403 | + |
404 | 404 | setValue: function(model, newValue, depsValues) { |
405 | 405 | var count = this.filters ? this.filters.length : 0; |
406 | 406 | while (count-- > 0) { |
|
0 commit comments