QUnit.test("Components can be instantiated with viewModel", function() { // These are the observables that would typically be outside the component’s scope var bindMap = new SimpleMap({inner: new SimpleMap({key: "original bind value"})}); var fromMap = new SimpleMap({inner: new SimpleMap({key: "original from value"})}); var toMap = new SimpleMap({inner: new SimpleMap({key: "original to value"})}); // Our component var ComponentConstructor = Component.extend({ tag: "new-instantiation-viewmodel", view: "Hello", ViewModel: { fromChildProp: "string", plainProp: "string", toParentProp: "string", twoWayProp: "string", nullProp: { default: function() { return 'bar'; } } } }); // Create a new instance of our component var componentInstance = new ComponentConstructor({ // Pass the viewModel with a mix of plain and observable values viewModel: { plainProp: "plain value", fromChildProp: value.from(fromMap, "inner.key"), toParentProp: value.to(toMap, "inner.key"), twoWayProp: value.bind(bindMap, "inner.key"), nullProp: null } }); var viewModel = componentInstance.viewModel; // Initial values are correct QUnit.equal(viewModel.fromChildProp, "original from value", "fromChildProp init"); QUnit.equal(viewModel.plainProp, "plain value", "plainProp init"); QUnit.equal(viewModel.toParentProp, undefined, "toParentProp init"); QUnit.equal(viewModel.twoWayProp, "original bind value", "twoWayProp init"); QUnit.equal(viewModel.nullProp, null, "nullProp init"); // Updating the fromChildProp fromMap.get("inner").set("key", "new from value"); QUnit.equal(viewModel.fromChildProp, "new from value", "viewModel updated after fromMap set"); // Updating the toParentProp viewModel.toParentProp = "new to value"; QUnit.equal(toMap.get("inner").get("key"), "new to value", "toMap updated after viewModel set"); // Updating the twoWayProp bindMap.get("inner").set("key", "new bind value"); QUnit.equal(viewModel.twoWayProp, "new bind value", "viewModel updated after bindMap set"); viewModel.twoWayProp = "newest bind value"; QUnit.equal(bindMap.get("inner").get("key"), "newest bind value", "bindMap updated after viewModel set"); });
QUnit.test("Component binding instantiation works as documented", function() { // These are the observables that would typically be outside the component’s scope var appVM = new SimpleMap({ family: new SimpleMap({ first: "Milo", last: "Flanders" }) }); // Our component var NameComponent = Component.extend({ tag: "name-component", view: "{{fullName}}", ViewModel: { givenName: "string", familyName: "string", get fullName() { return this.givenName + " " + this.familyName; } } }); // Create a new instance of our component var componentInstance = new NameComponent({ viewModel: { givenName: value.from(appVM, "family.first"), familyName: value.bind(appVM, "family.last"), fullName: value.to(appVM, "family.full") } }); var viewModel = componentInstance.viewModel; // Initial component values are correct QUnit.equal(viewModel.familyName, "Flanders", "component “bind” prop is correct"); QUnit.equal(viewModel.givenName, "Milo", "component “from” prop is correct"); QUnit.equal(viewModel.fullName, "Milo Flanders", "component “to” prop is correct"); // Initial map values are correct var family = appVM.get("family"); QUnit.equal(family.get("last"), "Flanders", "map “bind” prop is correct"); QUnit.equal(family.get("first"), "Milo", "map “from” prop is correct"); QUnit.equal(family.get("full"), "Milo Flanders", "map “to” prop is correct"); });
QUnit.test("component instantiation is not observable", function(){ var innerViewModel; var InnerComponent = Component.extend({ tag: "inner-component-to-make", view: "{{this.innerValue}}", ViewModel: { init: function(){ innerViewModel = this; }, innerValue: "any" } }); var count = 0; Component.extend({ tag: "outer-component-creator", view: "{{{ this.innerComponent }}}", ViewModel: { get innerComponent() { count++; return new InnerComponent({ viewModel: { innerValue: value.bind(this, "outerValue") } }); }, outerValue: "any" } }); var view = stache("<outer-component-creator/>"); view(); innerViewModel.innerValue = "SOME-VALUE"; QUnit.equal(count, 1, "only updated once"); });