Skip to content

Commit

Permalink
fix(change_detection): fixed reflect properties as attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
vsavkin committed Aug 21, 2015
1 parent b614639 commit a9ce454
Show file tree
Hide file tree
Showing 28 changed files with 168 additions and 142 deletions.
1 change: 1 addition & 0 deletions modules/angular2/change_detection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ export {
KeyValueDiffers,
KeyValueDiffer,
KeyValueDifferFactory

} from 'angular2/src/change_detection/change_detection';
1 change: 0 additions & 1 deletion modules/angular2/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,5 @@ export {
ViewDefinition,
DOCUMENT,
APP_ID,
DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES,
MAX_IN_MEMORY_ELEMENTS_PER_TEMPLATE
} from './src/render/render';
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
this.dispatcher.notifyOnBinding(this._currentBinding(), value);
}

protected logBindingUpdate(value: any): void {
this.dispatcher.logBindingUpdate(this._currentBinding(), value);
}

protected addChange(changes: StringMap<string, any>, oldValue: any,
newValue: any): StringMap<string, any> {
if (isBlank(changes)) {
Expand Down
3 changes: 2 additions & 1 deletion modules/angular2/src/change_detection/binding_record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ export class BindingRecord {

static createForDirective(ast: AST, propertyName: string, setter: SetterFn,
directiveRecord: DirectiveRecord): BindingRecord {
var t = new BindingTarget(DIRECTIVE, null, propertyName, null, ast.toString());
var elementIndex = directiveRecord.directiveIndex.elementIndex;
var t = new BindingTarget(DIRECTIVE, elementIndex, propertyName, null, ast.toString());
return new BindingRecord(DIRECTIVE, t, 0, ast, setter, null, directiveRecord);
}

Expand Down
44 changes: 27 additions & 17 deletions modules/angular2/src/change_detection/change_detection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,23 +84,26 @@ export const defaultKeyValueDiffers = CONST_EXPR(new KeyValueDiffers(keyValDiff)
// dart2js. See https://github.com/dart-lang/sdk/issues/23630 for details.
export var preGeneratedProtoDetectors: StringMap<string, Function> = {};

export const PROTO_CHANGE_DETECTOR = CONST_EXPR(new OpaqueToken('ProtoChangeDetectors'));

/**
* Implements change detection using a map of pregenerated proto detectors.
*/
@Injectable()
export class PreGeneratedChangeDetection extends ChangeDetection {
_dynamicChangeDetection: ChangeDetection;
_protoChangeDetectorFactories: StringMap<string, Function>;
_genConfig: ChangeDetectorGenConfig;

constructor(@Inject(PROTO_CHANGE_DETECTOR) @Optional() protoChangeDetectorsForTest?:
StringMap<string, Function>) {
constructor(config?: ChangeDetectorGenConfig,
protoChangeDetectorsForTest?: StringMap<string, Function>) {
super();
this._dynamicChangeDetection = new DynamicChangeDetection();
this._protoChangeDetectorFactories = isPresent(protoChangeDetectorsForTest) ?
protoChangeDetectorsForTest :
preGeneratedProtoDetectors;

this._genConfig =
isPresent(config) ? config : new ChangeDetectorGenConfig(assertionsEnabled(),
assertionsEnabled(), false);
}

static isSupported(): boolean { return PregenProtoChangeDetector.isSupported(); }
Expand All @@ -112,11 +115,8 @@ export class PreGeneratedChangeDetection extends ChangeDetection {
return this._dynamicChangeDetection.getProtoChangeDetector(id, definition);
}

get genConfig(): ChangeDetectorGenConfig { return this._genConfig; }
get generateDetectors(): boolean { return true; }

get genConfig(): ChangeDetectorGenConfig {
return new ChangeDetectorGenConfig(assertionsEnabled(), assertionsEnabled());
}
}


Expand All @@ -127,15 +127,21 @@ export class PreGeneratedChangeDetection extends ChangeDetection {
*/
@Injectable()
export class DynamicChangeDetection extends ChangeDetection {
_genConfig: ChangeDetectorGenConfig;

constructor(config?: ChangeDetectorGenConfig) {
super();
this._genConfig =
isPresent(config) ? config : new ChangeDetectorGenConfig(assertionsEnabled(),
assertionsEnabled(), false);
}

getProtoChangeDetector(id: string, definition: ChangeDetectorDefinition): ProtoChangeDetector {
return new DynamicProtoChangeDetector(definition);
}

get genConfig(): ChangeDetectorGenConfig { return this._genConfig; }
get generateDetectors(): boolean { return true; }

get genConfig(): ChangeDetectorGenConfig {
return new ChangeDetectorGenConfig(assertionsEnabled(), assertionsEnabled());
}
}

/**
Expand All @@ -145,17 +151,21 @@ export class DynamicChangeDetection extends ChangeDetection {
* {@link DynamicChangeDetection} and {@link PreGeneratedChangeDetection}.
*/
@Injectable()
@CONST()
export class JitChangeDetection extends ChangeDetection {
_genConfig: ChangeDetectorGenConfig;
constructor(config?: ChangeDetectorGenConfig) {
super();
this._genConfig =
isPresent(config) ? config : new ChangeDetectorGenConfig(assertionsEnabled(),
assertionsEnabled(), false);
}

static isSupported(): boolean { return JitProtoChangeDetector.isSupported(); }

getProtoChangeDetector(id: string, definition: ChangeDetectorDefinition): ProtoChangeDetector {
return new JitProtoChangeDetector(definition);
}

get genConfig(): ChangeDetectorGenConfig { return this._genConfig; }
get generateDetectors(): boolean { return true; }

get genConfig(): ChangeDetectorGenConfig {
return new ChangeDetectorGenConfig(assertionsEnabled(), assertionsEnabled());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ export class ChangeDetectorJITGenerator {
return new ${this._typeName}(dispatcher);
}
`;

return new Function(ABSTRACT_CHANGE_DETECTOR, UTIL, classDefinition)(AbstractChangeDetector,
ChangeDetectionUtil);
}
Expand Down Expand Up @@ -301,6 +300,7 @@ export class ChangeDetectorJITGenerator {

var newValue = this._names.getLocalName(r.selfIndex);
var oldValue = this._names.getFieldName(r.selfIndex);
var notifyDebug = this.genConfig.logBindingUpdate ? `this.logBindingUpdate(${newValue});` : "";

var br = r.bindingRecord;
if (br.target.isDirective()) {
Expand All @@ -309,12 +309,14 @@ export class ChangeDetectorJITGenerator {
return `
${this._genThrowOnChangeCheck(oldValue, newValue)}
${directiveProperty} = ${newValue};
${notifyDebug}
${IS_CHANGED_LOCAL} = true;
`;
} else {
return `
${this._genThrowOnChangeCheck(oldValue, newValue)}
this.notifyDispatcher(${newValue});
${notifyDebug}
`;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
var directiveIndex = bindingRecord.directiveRecord.directiveIndex;
bindingRecord.setter(this._getDirectiveFor(directiveIndex), change.currentValue);
}

if (this.genConfig.logBindingUpdate) {
super.logBindingUpdate(change.currentValue);
}
}

_addChange(bindingRecord: BindingRecord, change, changes) {
Expand Down
6 changes: 4 additions & 2 deletions modules/angular2/src/change_detection/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {ChangeDetectorRef} from './change_detector_ref';
*
* # Example
* ```javascript
* bootstrap(MyApp, [bind(ChangeDetection).toClass(DynamicChangeDetection)]);
* bootstrap(MyApp, [bind(ChangeDetection).toValue(new DynamicChangeDetection())]);
* ```
*/
@CONST()
Expand All @@ -49,6 +49,7 @@ export class DebugContext {
export interface ChangeDispatcher {
getDebugContext(elementIndex: number, directiveIndex: DirectiveIndex): DebugContext;
notifyOnBinding(bindingTarget: BindingTarget, value: any): void;
logBindingUpdate(bindingTarget: BindingTarget, value: any): void;
notifyOnAllChangesDone(): void;
}

Expand All @@ -74,7 +75,8 @@ export interface ChangeDetector {
export interface ProtoChangeDetector { instantiate(dispatcher: ChangeDispatcher): ChangeDetector; }

export class ChangeDetectorGenConfig {
constructor(public genCheckNoChanges: boolean, public genDebugInfo: boolean) {}
constructor(public genCheckNoChanges: boolean, public genDebugInfo: boolean,
public logBindingUpdate: boolean) {}
}

export class ChangeDetectorDefinition {
Expand Down
10 changes: 4 additions & 6 deletions modules/angular2/src/core/application_common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ import {Renderer, RenderCompiler} from 'angular2/src/render/api';
import {
DomRenderer,
DOCUMENT,
DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES,
DefaultDomCompiler,
APP_ID_RANDOM_BINDING,
MAX_IN_MEMORY_ELEMENTS_PER_TEMPLATE,
Expand All @@ -84,16 +83,15 @@ var _rootInjector: Injector;
var _rootBindings = [bind(Reflector).toValue(reflector), TestabilityRegistry];

function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
var bestChangeDetection: Type = DynamicChangeDetection;
var bestChangeDetection = new DynamicChangeDetection();
if (PreGeneratedChangeDetection.isSupported()) {
bestChangeDetection = PreGeneratedChangeDetection;
bestChangeDetection = new PreGeneratedChangeDetection();
} else if (JitChangeDetection.isSupported()) {
bestChangeDetection = JitChangeDetection;
bestChangeDetection = new JitChangeDetection();
}
return [
bind(DOCUMENT)
.toValue(DOM.defaultDoc()),
bind(DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES).toValue(false),
bind(APP_COMPONENT).toValue(appComponentType),
bind(APP_COMPONENT_REF_PROMISE)
.toFactory(
Expand Down Expand Up @@ -141,7 +139,7 @@ function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
DEFAULT_PIPES,
bind(IterableDiffers).toValue(defaultIterableDiffers),
bind(KeyValueDiffers).toValue(defaultKeyValueDiffers),
bind(ChangeDetection).toClass(bestChangeDetection),
bind(ChangeDetection).toValue(bestChangeDetection),
ViewLoader,
DirectiveResolver,
PipeResolver,
Expand Down
11 changes: 11 additions & 0 deletions modules/angular2/src/core/compiler/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ import {RenderEventDispatcher} from 'angular2/src/render/api';
import {ViewRef, ProtoViewRef, internalView} from './view_ref';
import {ElementRef} from './element_ref';
import {ProtoPipes} from 'angular2/src/core/pipes/pipes';
import {camelCaseToDashCase} from 'angular2/src/render/dom/util';

export {DebugContext} from 'angular2/src/change_detection/interfaces';

const REFLECT_PREFIX: string = 'ng-reflect-';

export class AppProtoViewMergeMapping {
renderProtoViewRef: renderApi.RenderProtoViewRef;
renderFragmentCount: number;
Expand Down Expand Up @@ -193,6 +196,14 @@ export class AppView implements ChangeDispatcher, RenderEventDispatcher {
}
}

logBindingUpdate(b: BindingTarget, value: any): void {
if (b.isDirective() || b.isElementProperty()) {
var elementRef = this.elementRefs[this.elementOffset + b.elementIndex];
this.renderer.setElementAttribute(
elementRef, `${REFLECT_PREFIX}${camelCaseToDashCase(b.name)}`, `${value}`);
}
}

notifyOnAllChangesDone(): void {
var eiCount = this.proto.elementBinders.length;
var ei = this.elementInjectors;
Expand Down
2 changes: 1 addition & 1 deletion modules/angular2/src/forms/directives/ng_model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ export class NgModel extends NgControl {
this.viewModel = newValue;
ObservableWrapper.callNext(this.update, newValue);
}
}
}
13 changes: 2 additions & 11 deletions modules/angular2/src/render/dom/dom_renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,19 @@ import {

import {TemplateCloner} from './template_cloner';

import {DOCUMENT, DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES} from './dom_tokens';
import {DOCUMENT} from './dom_tokens';

const REFLECT_PREFIX: string = 'ng-reflect-';


@Injectable()
export class DomRenderer extends Renderer {
_document;
_reflectPropertiesAsAttributes: boolean;

constructor(private _eventManager: EventManager,
private _domSharedStylesHost: DomSharedStylesHost,
private _templateCloner: TemplateCloner, @Inject(DOCUMENT) document,
@Inject(DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES) reflectPropertiesAsAttributes:
boolean) {
private _templateCloner: TemplateCloner, @Inject(DOCUMENT) document) {
super();
this._reflectPropertiesAsAttributes = reflectPropertiesAsAttributes;
this._document = document;
}

Expand Down Expand Up @@ -165,11 +161,6 @@ export class DomRenderer extends Renderer {
}
var view = resolveInternalDomView(location.renderView);
view.setElementProperty(location.renderBoundElementIndex, propertyName, propertyValue);
// Reflect the property value as an attribute value with ng-reflect- prefix.
if (this._reflectPropertiesAsAttributes) {
this.setElementAttribute(location, `${REFLECT_PREFIX}${camelCaseToDashCase(propertyName)}`,
`${propertyValue}`);
}
}

setElementAttribute(location: RenderElementRef, attributeName: string, attributeValue: string):
Expand Down
4 changes: 0 additions & 4 deletions modules/angular2/src/render/dom/dom_tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import {CONST_EXPR, StringWrapper, Math} from 'angular2/src/facade/lang';

export const DOCUMENT: OpaqueToken = CONST_EXPR(new OpaqueToken('DocumentToken'));

export const DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES: OpaqueToken =
CONST_EXPR(new OpaqueToken('DomReflectPropertiesAsAttributes'));


/**
* A unique id (string) for an angular application.
*/
Expand Down
4 changes: 1 addition & 3 deletions modules/angular2/src/test_lib/test_injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ import {RenderCompiler, Renderer} from 'angular2/src/render/api';
import {
DomRenderer,
DOCUMENT,
DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES,
DefaultDomCompiler,
APP_ID,
SharedStylesHost,
Expand Down Expand Up @@ -111,7 +110,6 @@ function _getAppBindings() {
bind(ElementSchemaRegistry).toValue(new DomElementSchemaRegistry()),
DomSharedStylesHost,
bind(SharedStylesHost).toAlias(DomSharedStylesHost),
bind(DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES).toValue(false),
ProtoViewFactory,
AppViewPool,
AppViewManager,
Expand All @@ -125,7 +123,7 @@ function _getAppBindings() {
DEFAULT_PIPES,
bind(IterableDiffers).toValue(defaultIterableDiffers),
bind(KeyValueDiffers).toValue(defaultKeyValueDiffers),
bind(ChangeDetection).toClass(DynamicChangeDetection),
bind(ChangeDetection).toValue(new DynamicChangeDetection()),
Log,
ViewLoader,
DynamicComponentLoader,
Expand Down
6 changes: 6 additions & 0 deletions modules/angular2/src/transform/common/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const CUSTOM_ANNOTATIONS_PARAM = 'custom_annotations';
const ENTRY_POINT_PARAM = 'entry_points';
const FORMAT_CODE_PARAM = 'format_code';
const GENERATE_CHANGE_DETECTORS_PARAM = 'generate_change_detectors';
const REFLECT_PROPERTIES_AS_ATTRIBUTES = 'reflectPropertiesAsAttributes';
const INIT_REFLECTOR_PARAM = 'init_reflector';
const INLINE_VIEWS_PARAM = 'inline_views';
const MIRROR_MODE_PARAM = 'mirror_mode';
Expand Down Expand Up @@ -43,6 +44,8 @@ class TransformerOptions {
/// Whether to create change detector classes for discovered `@View`s.
final bool generateChangeDetectors;

final bool reflectPropertiesAsAttributes;

/// The number of phases to spend optimizing output size.
/// Each additional phase adds time to the transformation but may decrease
/// final output size. There is a limit beyond which this will no longer
Expand All @@ -66,6 +69,7 @@ class TransformerOptions {
this.annotationMatcher,
this.optimizationPhases,
{this.generateChangeDetectors,
this.reflectPropertiesAsAttributes,
this.inlineViews,
this.formatCode});

Expand All @@ -78,6 +82,7 @@ class TransformerOptions {
int optimizationPhases: DEFAULT_OPTIMIZATION_PHASES,
bool inlineViews: true,
bool generateChangeDetectors: true,
bool reflectPropertiesAsAttributes: true,
bool formatCode: false}) {
if (reflectionEntryPoints == null || reflectionEntryPoints.isEmpty) {
reflectionEntryPoints = entryPoints;
Expand All @@ -94,6 +99,7 @@ class TransformerOptions {
annotationMatcher,
optimizationPhases,
generateChangeDetectors: generateChangeDetectors,
reflectPropertiesAsAttributes: reflectPropertiesAsAttributes,
inlineViews: inlineViews,
formatCode: formatCode);
}
Expand Down
Loading

0 comments on commit a9ce454

Please sign in to comment.