feat(view): reimplemented property setters using change detection
This commit is contained in:
12
modules/angular2/src/render/api.js
vendored
12
modules/angular2/src/render/api.js
vendored
@ -72,12 +72,14 @@ export class DirectiveBinder {
|
||||
// that replaced the values that should be extracted from the element
|
||||
// with a local name
|
||||
eventBindings: List<EventBinding>;
|
||||
hostPropertyBindings: Map<string, ASTWithSource>;
|
||||
constructor({
|
||||
directiveIndex, propertyBindings, eventBindings
|
||||
directiveIndex, propertyBindings, eventBindings, hostPropertyBindings
|
||||
}) {
|
||||
this.directiveIndex = directiveIndex;
|
||||
this.propertyBindings = propertyBindings;
|
||||
this.eventBindings = eventBindings;
|
||||
this.hostPropertyBindings = hostPropertyBindings;
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,17 +116,17 @@ export class DirectiveMetadata {
|
||||
selector:string;
|
||||
compileChildren:boolean;
|
||||
hostListeners:Map<string, string>;
|
||||
hostProperties:Map<string, string>;
|
||||
properties:Map<string, string>;
|
||||
setters:List<string>;
|
||||
readAttributes:List<string>;
|
||||
type:number;
|
||||
constructor({id, selector, compileChildren, hostListeners, properties, setters, readAttributes, type}) {
|
||||
constructor({id, selector, compileChildren, hostListeners, hostProperties, properties, readAttributes, type}) {
|
||||
this.id = id;
|
||||
this.selector = selector;
|
||||
this.compileChildren = isPresent(compileChildren) ? compileChildren : true;
|
||||
this.hostListeners = hostListeners;
|
||||
this.hostProperties = hostProperties;
|
||||
this.properties = properties;
|
||||
this.setters = setters;
|
||||
this.readAttributes = readAttributes;
|
||||
this.type = type;
|
||||
}
|
||||
@ -248,7 +250,7 @@ export class Renderer {
|
||||
|
||||
/**
|
||||
* Sets a property on an element.
|
||||
* Note: This will fail if the property was not mentioned previously as a propertySetter
|
||||
* Note: This will fail if the property was not mentioned previously as a host property
|
||||
* in the View.
|
||||
*/
|
||||
setElementProperty(view:ViewRef, elementIndex:number, propertyName:string, propertyValue:any):void {}
|
||||
|
@ -56,21 +56,21 @@ export class DirectiveParser extends CompileStep {
|
||||
this._selectorMatcher.match(cssSelector, (selector, directiveIndex) => {
|
||||
var elementBinder = current.bindElement();
|
||||
var directive = this._directives[directiveIndex];
|
||||
var directiveBinder = elementBinder.bindDirective(directiveIndex);
|
||||
var directiveBinderBuilder = elementBinder.bindDirective(directiveIndex);
|
||||
current.compileChildren = current.compileChildren && directive.compileChildren;
|
||||
if (isPresent(directive.properties)) {
|
||||
MapWrapper.forEach(directive.properties, (bindConfig, dirProperty) => {
|
||||
this._bindDirectiveProperty(dirProperty, bindConfig, current, directiveBinder);
|
||||
this._bindDirectiveProperty(dirProperty, bindConfig, current, directiveBinderBuilder);
|
||||
});
|
||||
}
|
||||
if (isPresent(directive.hostListeners)) {
|
||||
MapWrapper.forEach(directive.hostListeners, (action, eventName) => {
|
||||
this._bindDirectiveEvent(eventName, action, current, directiveBinder);
|
||||
this._bindDirectiveEvent(eventName, action, current, directiveBinderBuilder);
|
||||
});
|
||||
}
|
||||
if (isPresent(directive.setters)) {
|
||||
ListWrapper.forEach(directive.setters, (propertyName) => {
|
||||
elementBinder.bindPropertySetter(propertyName);
|
||||
if (isPresent(directive.hostProperties)) {
|
||||
MapWrapper.forEach(directive.hostProperties, (hostPropertyName, directivePropertyName) => {
|
||||
this._bindHostProperty(hostPropertyName, directivePropertyName, current, directiveBinderBuilder);
|
||||
});
|
||||
}
|
||||
if (isPresent(directive.readAttributes)) {
|
||||
@ -102,7 +102,7 @@ export class DirectiveParser extends CompileStep {
|
||||
});
|
||||
}
|
||||
|
||||
_bindDirectiveProperty(dirProperty, bindConfig, compileElement, directiveBinder) {
|
||||
_bindDirectiveProperty(dirProperty, bindConfig, compileElement, directiveBinderBuilder) {
|
||||
var pipes = this._splitBindConfig(bindConfig);
|
||||
var elProp = ListWrapper.removeAt(pipes, 0);
|
||||
|
||||
@ -124,21 +124,27 @@ export class DirectiveParser extends CompileStep {
|
||||
// Bindings are optional, so this binding only needs to be set up if an expression is given.
|
||||
if (isPresent(bindingAst)) {
|
||||
var fullExpAstWithBindPipes = this._parser.addPipes(bindingAst, pipes);
|
||||
directiveBinder.bindProperty(
|
||||
directiveBinderBuilder.bindProperty(
|
||||
dirProperty, fullExpAstWithBindPipes
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_bindDirectiveEvent(eventName, action, compileElement, directiveBinder) {
|
||||
_bindDirectiveEvent(eventName, action, compileElement, directiveBinderBuilder) {
|
||||
var ast = this._parser.parseAction(action, compileElement.elementDescription);
|
||||
if (StringWrapper.contains(eventName, EVENT_TARGET_SEPARATOR)) {
|
||||
var parts = eventName.split(EVENT_TARGET_SEPARATOR);
|
||||
directiveBinder.bindEvent(parts[1], ast, parts[0]);
|
||||
directiveBinderBuilder.bindEvent(parts[1], ast, parts[0]);
|
||||
} else {
|
||||
directiveBinder.bindEvent(eventName, ast);
|
||||
directiveBinderBuilder.bindEvent(eventName, ast);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
_bindHostProperty(hostPropertyName, directivePropertyName, compileElement, directiveBinderBuilder) {
|
||||
var ast = this._parser.parseBinding(directivePropertyName,
|
||||
`hostProperties of ${compileElement.elementDescription}`);
|
||||
directiveBinderBuilder.bindHostProperty(hostPropertyName, ast);
|
||||
}
|
||||
|
||||
_splitBindConfig(bindConfig:string) {
|
||||
|
@ -5,7 +5,6 @@ import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
import {
|
||||
ASTWithSource, AST, AstTransformer, AccessMember, LiteralArray, ImplicitReceiver
|
||||
} from 'angular2/change_detection';
|
||||
import {SetterFn} from 'angular2/src/reflection/types';
|
||||
|
||||
import {RenderProtoView} from './proto_view';
|
||||
import {ElementBinder, Event} from './element_binder';
|
||||
@ -57,17 +56,26 @@ export class ProtoViewBuilder {
|
||||
var apiElementBinders = [];
|
||||
ListWrapper.forEach(this.elements, (ebb) => {
|
||||
var propertySetters = MapWrapper.create();
|
||||
var apiDirectiveBinders = ListWrapper.map(ebb.directives, (db) => {
|
||||
ebb.eventBuilder.merge(db.eventBuilder);
|
||||
|
||||
var apiDirectiveBinders = ListWrapper.map(ebb.directives, (dbb) => {
|
||||
ebb.eventBuilder.merge(dbb.eventBuilder);
|
||||
|
||||
MapWrapper.forEach(dbb.hostPropertyBindings, (_, hostPropertyName) => {
|
||||
MapWrapper.set(propertySetters, hostPropertyName, setterFactory(hostPropertyName));
|
||||
});
|
||||
|
||||
return new api.DirectiveBinder({
|
||||
directiveIndex: db.directiveIndex,
|
||||
propertyBindings: db.propertyBindings,
|
||||
eventBindings: db.eventBindings
|
||||
directiveIndex: dbb.directiveIndex,
|
||||
propertyBindings: dbb.propertyBindings,
|
||||
eventBindings: dbb.eventBindings,
|
||||
hostPropertyBindings: dbb.hostPropertyBindings
|
||||
});
|
||||
});
|
||||
MapWrapper.forEach(ebb.propertySetters, (setter, propertyName) => {
|
||||
MapWrapper.set(propertySetters, propertyName, setter);
|
||||
|
||||
MapWrapper.forEach(ebb.propertyBindings, (_, propertyName) => {
|
||||
MapWrapper.set(propertySetters, propertyName, setterFactory(propertyName));
|
||||
});
|
||||
|
||||
var nestedProtoView =
|
||||
isPresent(ebb.nestedProtoView) ? ebb.nestedProtoView.build() : null;
|
||||
var parentIndex = isPresent(ebb.parent) ? ebb.parent.index : -1;
|
||||
@ -119,7 +127,6 @@ export class ElementBinderBuilder {
|
||||
textBindingIndices: List<number>;
|
||||
textBindings: List<ASTWithSource>;
|
||||
contentTagSelector:string;
|
||||
propertySetters: Map<string, SetterFn>;
|
||||
readAttributes: Map<string, string>;
|
||||
componentId: string;
|
||||
|
||||
@ -137,7 +144,6 @@ export class ElementBinderBuilder {
|
||||
this.textBindings = [];
|
||||
this.textBindingIndices = [];
|
||||
this.contentTagSelector = null;
|
||||
this.propertySetters = MapWrapper.create();
|
||||
this.componentId = null;
|
||||
this.readAttributes = MapWrapper.create();
|
||||
}
|
||||
@ -172,11 +178,10 @@ export class ElementBinderBuilder {
|
||||
|
||||
bindProperty(name, expression) {
|
||||
MapWrapper.set(this.propertyBindings, name, expression);
|
||||
this.bindPropertySetter(name);
|
||||
}
|
||||
|
||||
bindPropertySetter(name) {
|
||||
MapWrapper.set(this.propertySetters, name, setterFactory(name));
|
||||
//TODO: required for Dart transformers. Remove when Dart transformers
|
||||
//run all the steps of the render compiler
|
||||
setterFactory(name);
|
||||
}
|
||||
|
||||
bindVariable(name, value) {
|
||||
@ -216,12 +221,14 @@ export class ElementBinderBuilder {
|
||||
export class DirectiveBuilder {
|
||||
directiveIndex:number;
|
||||
propertyBindings: Map<string, ASTWithSource>;
|
||||
hostPropertyBindings: Map<string, ASTWithSource>;
|
||||
eventBindings: List<api.EventBinding>;
|
||||
eventBuilder: EventBuilder;
|
||||
|
||||
constructor(directiveIndex) {
|
||||
this.directiveIndex = directiveIndex;
|
||||
this.propertyBindings = MapWrapper.create();
|
||||
this.hostPropertyBindings = MapWrapper.create();
|
||||
this.eventBindings = ListWrapper.create();
|
||||
this.eventBuilder = new EventBuilder();
|
||||
}
|
||||
@ -230,6 +237,10 @@ export class DirectiveBuilder {
|
||||
MapWrapper.set(this.propertyBindings, name, expression);
|
||||
}
|
||||
|
||||
bindHostProperty(name, expression) {
|
||||
MapWrapper.set(this.hostPropertyBindings, name, expression);
|
||||
}
|
||||
|
||||
bindEvent(name, expression, target = null) {
|
||||
ListWrapper.push(this.eventBindings, this.eventBuilder.add(name, expression, target));
|
||||
}
|
||||
|
Reference in New Issue
Block a user