mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Fix view.lookup to not take dependencies
The template compiler assumes that single-segment paths like {{foo}}, compiled into view.lookup(“foo”), don’t take dependencies, returning a function if there is anything reactive going on. We violated that in the Blaze refactor, meaning that #with might re-render its contents when its argument changes!
Tests to add:
* UI.dynamic doesn’t re-create template when enclosing data context changes.
* UI.dynamic doesn’t re-create template when “data” argument changes
* Coverage for the “..” and “foo” cases in lookup.js
Tests to fix: “simple helper”
This commit is contained in:
@@ -28,6 +28,10 @@ var wrapHelper = function (f) {
|
|||||||
// If a function is found, it is bound to the object it
|
// If a function is found, it is bound to the object it
|
||||||
// was found on. Returns a function,
|
// was found on. Returns a function,
|
||||||
// non-function value, or null.
|
// non-function value, or null.
|
||||||
|
//
|
||||||
|
// NOTE: This function must not establish any reactive
|
||||||
|
// dependencies. If there is any reactivity in the
|
||||||
|
// value, lookup should return a function.
|
||||||
Blaze.View.prototype.lookup = function (name, _options) {
|
Blaze.View.prototype.lookup = function (name, _options) {
|
||||||
var template = this.template;
|
var template = this.template;
|
||||||
var lookupTemplate = _options && _options.template;
|
var lookupTemplate = _options && _options.template;
|
||||||
@@ -38,7 +42,7 @@ Blaze.View.prototype.lookup = function (name, _options) {
|
|||||||
if (!/^(\.)+$/.test(name))
|
if (!/^(\.)+$/.test(name))
|
||||||
throw new Error("id starting with dot must be a series of dots");
|
throw new Error("id starting with dot must be a series of dots");
|
||||||
|
|
||||||
return Blaze._parentData(name.length - 1);
|
return Blaze._parentData(name.length - 1, true /*_functionWrapped*/);
|
||||||
|
|
||||||
} else if (template && (name in template)) {
|
} else if (template && (name in template)) {
|
||||||
return wrapHelper(bindToCurrentDataIfIsFunction(template[name]));
|
return wrapHelper(bindToCurrentDataIfIsFunction(template[name]));
|
||||||
@@ -47,29 +51,37 @@ Blaze.View.prototype.lookup = function (name, _options) {
|
|||||||
} else if (UI._globalHelpers[name]) {
|
} else if (UI._globalHelpers[name]) {
|
||||||
return wrapHelper(bindToCurrentDataIfIsFunction(UI._globalHelpers[name]));
|
return wrapHelper(bindToCurrentDataIfIsFunction(UI._globalHelpers[name]));
|
||||||
} else {
|
} else {
|
||||||
var data = Blaze.getCurrentData();
|
return function () {
|
||||||
if (data)
|
var data = Blaze.getCurrentData();
|
||||||
return wrapHelper(bindIfIsFunction(data[name], data));
|
if (lookupTemplate && ! (data && data[name]))
|
||||||
|
throw new Error("No such template: " + name);
|
||||||
|
if (! data)
|
||||||
|
return null;
|
||||||
|
var x = data[name];
|
||||||
|
if (typeof x !== 'function')
|
||||||
|
return x;
|
||||||
|
return x.apply(data, arguments);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implement Spacebars' {{../..}}.
|
// Implement Spacebars' {{../..}}.
|
||||||
// @param height {Number} The number of '..'s
|
// @param height {Number} The number of '..'s
|
||||||
Blaze._parentData = function (height) {
|
Blaze._parentData = function (height, _functionWrapped) {
|
||||||
var theWith = Blaze.getCurrentView('with');
|
var theWith = Blaze.getCurrentView('with');
|
||||||
for (var i = 0; (i < height) && theWith; i++) {
|
for (var i = 0; (i < height) && theWith; i++) {
|
||||||
theWith = Blaze.getParentView(theWith, 'with');
|
theWith = Blaze.getParentView(theWith, 'with');
|
||||||
}
|
}
|
||||||
|
|
||||||
return (theWith ? theWith.dataVar.get() : null);
|
if (! theWith)
|
||||||
|
return null;
|
||||||
|
if (_functionWrapped)
|
||||||
|
return function () { return theWith.dataVar.get(); };
|
||||||
|
return theWith.dataVar.get();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Blaze.View.prototype.lookupTemplate = function (name) {
|
Blaze.View.prototype.lookupTemplate = function (name) {
|
||||||
var result = this.lookup(name, {template:true});
|
return this.lookup(name, {template:true});
|
||||||
|
|
||||||
if (! result)
|
|
||||||
throw new Error("No such template: " + name);
|
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user