diff --git a/layout-test.html b/layout-test.html
index 3d7f2c8..eaa0a2e 100644
--- a/layout-test.html
+++ b/layout-test.html
@@ -26,6 +26,15 @@
{{> yield region="footer"}}
+
+ {{#with childData}}
+ {{> yield}}
+ {{/with}}
+ {{#with childData}}
+ {{> yield region="footer"}}
+ {{/with}}
+
+
child {{title}}
@@ -58,3 +67,11 @@
callback
+
+
+ {{#with title="ok"}}
+ {{#Layout template="LayoutWithOneYield"}}
+ inner{{title}}
+ {{/Layout}}
+ {{/with}}
+
diff --git a/layout-test.js b/layout-test.js
index f6b6b97..a151ad9 100644
--- a/layout-test.js
+++ b/layout-test.js
@@ -98,6 +98,12 @@ Tinytest.add('layout - default main region using Layout template', function (tes
});
});
+Tinytest.add('layout - default data context using Layout template', function (test) {
+ withRenderedComponent(Template.DefaultDataForLayout, function (cmp, screen) {
+ test.equal(screen.innerHTML.compact(), 'layoutinnerok', 'default data context should be outer data context');
+ });
+});
+
Tinytest.add('layout - dynamic yield regions', function (test) {
withRenderedLayout({template: 'LayoutWithTwoYields'}, function (layout, screen) {
var renderedCount = 1;
@@ -224,7 +230,6 @@ Tinytest.add('layout - region templates not found in lookup', function (test) {
});
-
// SEE IR#276 for detailed discussion
Tinytest.add('layout - Templates render with correct data even if setData is called after setRegion', function (test) {
withRenderedLayout({template: 'LayoutWithOneYield'}, function (layout, screen) {
@@ -243,4 +248,27 @@ Tinytest.add('layout - Templates render with correct data even if setData is cal
Deps.flush();
test.equal(screen.innerHTML.compact(), 'layoutcallback');
});
-});
\ No newline at end of file
+});
+
+// XXX: This test doesn't work.
+// To be totally honest, I'm not sure how it *should* work -- should
+// the yield be getting the data context of the with block? Maybe..
+// perhaps yield.data() should look at parent's data (modolo __isTemplateWith)
+// just like layout does.
+//
+// Tinytest.add('layout - set data via with', function (test) {
+// withRenderedLayout({template: 'LayoutThatSetsData'}, function (layout, screen) {
+// layout.setRegion('main', 'ChildWithData');
+// layout.setRegion('footer', 'FooterWithData');
+//
+// layout.setData({
+// title: 'parentTitle',
+// childData: {
+// title: 'childTitle'
+// }
+// });
+//
+// Deps.flush();
+// test.equal(screen.innerHTML.compact(), 'childchildTitlefooterchildTitle');
+// });
+// });
diff --git a/layout.js b/layout.js
index 454f7c0..840da23 100644
--- a/layout.js
+++ b/layout.js
@@ -104,7 +104,7 @@ Layout = UI.Component.extend({
var tmplDep = new Deps.Dependency;
// get the initial data value
- var data = Deps.nonreactive(function () { return self.get(); });
+ var data, dataSet = false;
var dataDep = new Deps.Dependency;
var regions = this._regions = new ReactiveDict;
var content = this.__content;
@@ -136,10 +136,26 @@ Layout = UI.Component.extend({
var cachedData = Deps.cache(function () {
log('return data()');
dataDep.depend();
- return data;
+ if (dataSet) {
+ return data;
+ } else {
+ // find the closest parent with a data context.
+ // If it's the direct parent, and it has `__isTemplateWith` set,
+ // then it's because we have `{{#Layout foo=bar}}` and we should ignore
+ var parent = self.parent;
+ if (parent) {
+ if (parent.__isTemplateWith)
+ parent = parent.parent;
+ return getComponentData(parent);
+ } else {
+ // the only time we don't have a parent is when we are in tests really
+ return null
+ }
+ }
});
this.setData = function (value) {
+ dataSet = true;
log('setData', value);
if (!EJSON.equals(value, data)) {
data = value;
@@ -204,6 +220,12 @@ Layout = UI.Component.extend({
// reset the data function to use the layout's
// data
this.data = function () {
+ // XXX: should we be instead trying to sensibly get parent's
+ // data -- much like layout.getData() does?
+ // then we'd expect to inherit layout.getData() (via layout.render)
+ // unless we wrapped our {{> yield}} in a with.
+ // is this what users would expect?
+ // see 'layout - set data via with' test
return layout.getData();
};
},