diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index 901a10f57b..65c59d14b6 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -63,6 +63,7 @@ export { p as ɵp, pD as ɵpD, a as ɵa, + k as ɵk, s as ɵs, t as ɵt, v as ɵv, diff --git a/packages/core/test/render3/compiler_canonical/elements_spec.ts b/packages/core/test/render3/compiler_canonical/elements_spec.ts index 7b13dbd1fa..046a11a9d8 100644 --- a/packages/core/test/render3/compiler_canonical/elements_spec.ts +++ b/packages/core/test/render3/compiler_canonical/elements_spec.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ +import {browserDetection} from '@angular/platform-browser/testing/src/browser_util'; import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core'; import * as $r3$ from '../../../src/core_render3_private_export'; import {renderComponent, toHtml} from '../render_util'; @@ -89,4 +90,179 @@ describe('elements', () => { const listenerComp = renderComponent(ListenerComp); expect(toHtml(listenerComp)).toEqual(''); }); + + describe('bindings', () => { + it('should bind to property', () => { + type $MyComponent$ = MyComponent; + + @Component({selector: 'my-component', template: `
`}) + class MyComponent { + someProperty: string = 'initial'; + // NORMATIVE + static ngComponentDef = $r3$.ɵdefineComponent({ + type: MyComponent, + tag: 'my-component', + factory: function MyComponent_Factory() { return new MyComponent(); }, + template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { + if (cm) { + $r3$.ɵE(0, 'div'); + $r3$.ɵe(); + } + $r3$.ɵp(0, 'id', $r3$.ɵb(ctx.someProperty)); + } + }); + // /NORMATIVE + } + + const comp = renderComponent(MyComponent); + expect(toHtml(comp)).toEqual('
'); + + comp.someProperty = 'changed'; + $r3$.ɵdetectChanges(comp); + expect(toHtml(comp)).toEqual('
'); + }); + + it('should bind to attribute', () => { + type $MyComponent$ = MyComponent; + + @Component({selector: 'my-component', template: `
`}) + class MyComponent { + someAttribute: string = 'initial'; + // NORMATIVE + static ngComponentDef = $r3$.ɵdefineComponent({ + type: MyComponent, + tag: 'my-component', + factory: function MyComponent_Factory() { return new MyComponent(); }, + template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { + if (cm) { + $r3$.ɵE(0, 'div'); + $r3$.ɵe(); + } + $r3$.ɵa(0, 'title', $r3$.ɵb(ctx.someAttribute)); + } + }); + // /NORMATIVE + } + + const comp = renderComponent(MyComponent); + expect(toHtml(comp)).toEqual('
'); + + comp.someAttribute = 'changed'; + $r3$.ɵdetectChanges(comp); + expect(toHtml(comp)).toEqual('
'); + }); + + it('should bind to a specific class', () => { + type $MyComponent$ = MyComponent; + + @Component({selector: 'my-component', template: `
`}) + class MyComponent { + someFlag: boolean = false; + // NORMATIVE + static ngComponentDef = $r3$.ɵdefineComponent({ + type: MyComponent, + tag: 'my-component', + factory: function MyComponent_Factory() { return new MyComponent(); }, + template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { + if (cm) { + $r3$.ɵE(0, 'div'); + $r3$.ɵe(); + } + $r3$.ɵk(0, 'foo', $r3$.ɵb(ctx.someFlag)); + } + }); + // /NORMATIVE + } + + const comp = renderComponent(MyComponent); + expect(toHtml(comp)).toEqual('
'); + + comp.someFlag = true; + $r3$.ɵdetectChanges(comp); + expect(toHtml(comp)).toEqual('
'); + }); + + it('should bind to a specific style', () => { + type $MyComponent$ = MyComponent; + + @Component({ + selector: 'my-component', + template: `
` + }) + class MyComponent { + someColor: string = 'red'; + someWidth: number = 50; + // NORMATIVE + static ngComponentDef = $r3$.ɵdefineComponent({ + type: MyComponent, + tag: 'my-component', + factory: function MyComponent_Factory() { return new MyComponent(); }, + template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { + if (cm) { + $r3$.ɵE(0, 'div'); + $r3$.ɵe(); + } + $r3$.ɵs(0, 'color', $r3$.ɵb(ctx.someColor)); + $r3$.ɵs(0, 'width', $r3$.ɵb(ctx.someWidth), 'px'); + } + }); + // /NORMATIVE + } + + const comp = renderComponent(MyComponent); + if (browserDetection.isIE) { + expect(toHtml(comp)).toEqual('
'); + } else { + expect(toHtml(comp)).toEqual('
'); + } + + comp.someColor = 'blue'; + comp.someWidth = 100; + $r3$.ɵdetectChanges(comp); + if (browserDetection.isIE) { + expect(toHtml(comp)).toEqual('
'); + } else { + expect(toHtml(comp)).toEqual('
'); + } + }); + + it('should bind to many and keep order', () => { + type $MyComponent$ = MyComponent; + + // NORMATIVE + const $e0_attrs$ = ['style', 'color: red;']; + // /NORMATIVE + + @Component({ + selector: 'my-component', + template: + `
` + }) + class MyComponent { + someString: string = 'initial'; + // NORMATIVE + static ngComponentDef = $r3$.ɵdefineComponent({ + type: MyComponent, + tag: 'my-component', + factory: function MyComponent_Factory() { return new MyComponent(); }, + template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { + if (cm) { + $r3$.ɵE(0, 'div', $e0_attrs$); + $r3$.ɵe(); + } + $r3$.ɵp(0, 'id', $r3$.ɵb(ctx.someString + 1)); + $r3$.ɵk(0, 'foo', $r3$.ɵb(ctx.someString == 'initial')); + } + }); + // /NORMATIVE + } + + const comp = renderComponent(MyComponent); + expect(toHtml(comp)).toEqual('
'); + + comp.someString = 'changed'; + $r3$.ɵdetectChanges(comp); + expect(toHtml(comp)).toEqual('
'); + }); + }); });