Tobias Bosch 7ae23adaff feat(core): speed up view creation via code gen for view factories.
BREAKING CHANGE:
- Platform pipes can only contain types and arrays of types,
  but no bindings any more.
- When using transformers, platform pipes need to be specified explicitly
  in the pubspec.yaml via the new config option
  `platform_pipes`.
- `Compiler.compileInHost` now returns a `HostViewFactoryRef`
- Component view is not yet created when component constructor is called.
  -> use `onInit` lifecycle callback to access the view of a component
- `ViewRef#setLocal` has been moved to new type `EmbeddedViewRef`
- `internalView` is gone, use `EmbeddedViewRef.rootNodes` to access
  the root nodes of an embedded view
- `renderer.setElementProperty`, `..setElementStyle`, `..setElementAttribute` now
  take a native element instead of an ElementRef
- `Renderer` interface now operates on plain native nodes,
  instead of `RenderElementRef`s or `RenderViewRef`s

Closes #5993
2016-01-05 08:56:46 -08:00

98 lines
3.0 KiB
TypeScript

import {
DoCheck,
KeyValueDiffer,
KeyValueDiffers,
ElementRef,
Directive,
Renderer
} from 'angular2/core';
import {isPresent, isBlank, print} from 'angular2/src/facade/lang';
/**
* The `NgStyle` directive changes styles based on a result of expression evaluation.
*
* An expression assigned to the `ngStyle` property must evaluate to an object and the
* corresponding element styles are updated based on changes to this object. Style names to update
* are taken from the object's keys, and values - from the corresponding object's values.
*
* ### Syntax
*
* - `<div [ngStyle]="{'font-style': style}"></div>`
* - `<div [ngStyle]="styleExp"></div>` - here the `styleExp` must evaluate to an object
*
* ### Example ([live demo](http://plnkr.co/edit/YamGS6GkUh9GqWNQhCyM?p=preview)):
*
* ```
* import {Component} from 'angular2/core';
* import {NgStyle} from 'angular2/common';
*
* @Component({
* selector: 'ngStyle-example',
* template: `
* <h1 [ngStyle]="{'font-style': style, 'font-size': size, 'font-weight': weight}">
* Change style of this text!
* </h1>
*
* <hr>
*
* <label>Italic: <input type="checkbox" (change)="changeStyle($event)"></label>
* <label>Bold: <input type="checkbox" (change)="changeWeight($event)"></label>
* <label>Size: <input type="text" [value]="size" (change)="size = $event.target.value"></label>
* `,
* directives: [NgStyle]
* })
* export class NgStyleExample {
* style = 'normal';
* weight = 'normal';
* size = '20px';
*
* changeStyle($event: any) {
* this.style = $event.target.checked ? 'italic' : 'normal';
* }
*
* changeWeight($event: any) {
* this.weight = $event.target.checked ? 'bold' : 'normal';
* }
* }
* ```
*
* In this example the `font-style`, `font-size` and `font-weight` styles will be updated
* based on the `style` property's value changes.
*/
@Directive({selector: '[ngStyle]', inputs: ['rawStyle: ngStyle']})
export class NgStyle implements DoCheck {
/** @internal */
_rawStyle;
/** @internal */
_differ: KeyValueDiffer;
constructor(private _differs: KeyValueDiffers, private _ngEl: ElementRef,
private _renderer: Renderer) {}
set rawStyle(v) {
this._rawStyle = v;
if (isBlank(this._differ) && isPresent(v)) {
this._differ = this._differs.find(this._rawStyle).create(null);
}
}
ngDoCheck() {
if (isPresent(this._differ)) {
var changes = this._differ.diff(this._rawStyle);
if (isPresent(changes)) {
this._applyChanges(changes);
}
}
}
private _applyChanges(changes: any): void {
changes.forEachAddedItem((record) => { this._setStyle(record.key, record.currentValue); });
changes.forEachChangedItem((record) => { this._setStyle(record.key, record.currentValue); });
changes.forEachRemovedItem((record) => { this._setStyle(record.key, null); });
}
private _setStyle(name: string, val: string): void {
this._renderer.setElementStyle(this._ngEl.nativeElement, name, val);
}
}