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"}} + + @@ -58,3 +67,11 @@ + + 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(); }; },