feat(view): add onChange implementation to view.
This commit is contained in:
@ -118,7 +118,6 @@ export class ProtoElementInjector extends TreeNode {
|
||||
query_keyId1:int;
|
||||
|
||||
textNodes:List<int>;
|
||||
hasProperties:boolean;
|
||||
events:Map<string, Expression>;
|
||||
|
||||
elementInjector:ElementInjector;
|
||||
@ -144,8 +143,10 @@ export class ProtoElementInjector extends TreeNode {
|
||||
@FIELD('_key7:int')
|
||||
@FIELD('_key8:int')
|
||||
@FIELD('_key9:int')
|
||||
@FIELD('textNodes:List<int>')
|
||||
constructor(parent:ProtoElementInjector, bindings:List, textNodes:List) {
|
||||
@FIELD('textNodeIndices:List<int>')
|
||||
@FIELD('hasElementPropertyBindings:bool')
|
||||
constructor(parent:ProtoElementInjector, bindings:List, textNodeIndices:List,
|
||||
hasElementPropertyBindings:boolean) {
|
||||
super(parent);
|
||||
|
||||
this._elementInjector = null;
|
||||
@ -177,10 +178,8 @@ export class ProtoElementInjector extends TreeNode {
|
||||
throw 'Maximum number of directives per element has been reached.';
|
||||
}
|
||||
|
||||
this.textNodes = textNodes;
|
||||
|
||||
// dummy fields to make analyzer happy
|
||||
this.hasProperties = false;
|
||||
this.textNodeIndices = textNodeIndices;
|
||||
this.hasElementPropertyBindings = hasElementPropertyBindings;
|
||||
}
|
||||
|
||||
instantiate({view}):ElementInjector {
|
||||
@ -418,5 +417,28 @@ export class ElementInjector extends TreeNode {
|
||||
if (p._keyId9 === keyId) return this._obj9;
|
||||
return _undefined;
|
||||
}
|
||||
|
||||
getAtIndex(index:int) {
|
||||
if (index == 0) return this._obj0;
|
||||
if (index == 1) return this._obj1;
|
||||
if (index == 2) return this._obj2;
|
||||
if (index == 3) return this._obj3;
|
||||
if (index == 4) return this._obj4;
|
||||
if (index == 5) return this._obj5;
|
||||
if (index == 6) return this._obj6;
|
||||
if (index == 7) return this._obj7;
|
||||
if (index == 8) return this._obj8;
|
||||
if (index == 9) return this._obj9;
|
||||
throw new OutOfBoundsAccess(index);
|
||||
}
|
||||
}
|
||||
|
||||
class OutOfBoundsAccess extends Error {
|
||||
constructor(index) {
|
||||
this.message = `Index ${index} is out-of-bounds.`;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.message;
|
||||
}
|
||||
}
|
||||
|
@ -23,14 +23,15 @@ export class View {
|
||||
/// to keep track of the nodes.
|
||||
@FIELD('final nodes:List<Node>')
|
||||
@FIELD('final onChangeDispatcher:OnChangeDispatcher')
|
||||
constructor(fragment:DocumentFragment, elementInjector:List, rootElementInjectors:List, textNodes:List) {
|
||||
constructor(fragment:DocumentFragment, elementInjector:List,
|
||||
rootElementInjectors:List, textNodes:List, bindElements:List) {
|
||||
this.fragment = fragment;
|
||||
this.nodes = ListWrapper.clone(fragment.childNodes);
|
||||
this.elementInjectors = elementInjector;
|
||||
this.rootElementInjectors = rootElementInjectors;
|
||||
this.onChangeDispatcher = null;
|
||||
this.textNodes = textNodes;
|
||||
this.bindElements = null;
|
||||
this.bindElements = bindElements;
|
||||
}
|
||||
|
||||
onRecordChange(record:Record, target) {
|
||||
@ -39,7 +40,7 @@ export class View {
|
||||
// we know that it is DirectivePropertyMemento
|
||||
var directiveMemento:DirectivePropertyMemento = target;
|
||||
directiveMemento.invoke(record, this.elementInjectors);
|
||||
} else if (target instanceof ElementPropertyMemento) {
|
||||
} else if (target instanceof ElementPropertyMemento) {
|
||||
var elementMemento:ElementPropertyMemento = target;
|
||||
elementMemento.invoke(record, this.bindElements);
|
||||
} else {
|
||||
@ -83,8 +84,10 @@ export class ProtoView {
|
||||
var elementInjectors = ProtoView._createElementInjectors(elements, protos);
|
||||
var rootElementInjectors = ProtoView._rootElementInjectors(elementInjectors);
|
||||
var textNodes = ProtoView._textNodes(elements, protos);
|
||||
var bindElements = ProtoView._bindElements(elements, protos);
|
||||
|
||||
return new View(fragment, elementInjectors, rootElementInjectors, textNodes);
|
||||
return new View(fragment, elementInjectors, rootElementInjectors, textNodes,
|
||||
bindElements);
|
||||
}
|
||||
|
||||
static _createElementInjectors(elements, protos) {
|
||||
@ -92,7 +95,11 @@ export class ProtoView {
|
||||
for (var i = 0; i < protos.length; ++i) {
|
||||
injectors[i] = ProtoView._createElementInjector(elements[i], protos[i]);
|
||||
}
|
||||
ListWrapper.forEach(protos, p => p.clearElementInjector());
|
||||
// Cannot be rolled into loop above, because parentInjector pointers need
|
||||
// to be set on the children.
|
||||
for (var i = 0; i < protos.length; ++i) {
|
||||
protos[i].clearElementInjector();
|
||||
}
|
||||
return injectors;
|
||||
}
|
||||
|
||||
@ -108,16 +115,26 @@ export class ProtoView {
|
||||
static _textNodes(elements, protos) {
|
||||
var textNodes = [];
|
||||
for (var i = 0; i < protos.length; ++i) {
|
||||
ProtoView._collectTextNodes(textNodes, elements[i], protos[i]);
|
||||
ProtoView._collectTextNodes(textNodes, elements[i],
|
||||
protos[i].textNodeIndices);
|
||||
}
|
||||
return textNodes;
|
||||
}
|
||||
|
||||
static _collectTextNodes(allTextNodes, element, proto) {
|
||||
static _bindElements(elements, protos):List<Element> {
|
||||
var bindElements = [];
|
||||
for (var i = 0; i < protos.length; ++i) {
|
||||
if (protos[i].hasElementPropertyBindings) ListWrapper.push(
|
||||
bindElements, elements[i]);
|
||||
}
|
||||
return bindElements;
|
||||
}
|
||||
|
||||
static _collectTextNodes(allTextNodes, element, indices) {
|
||||
var childNodes = DOM.childNodes(element);
|
||||
ListWrapper.forEach(proto.textNodes, (i) => {
|
||||
ListWrapper.push(allTextNodes, childNodes[i]);
|
||||
});
|
||||
for (var i = 0; i < indices.length; ++i) {
|
||||
ListWrapper.push(allTextNodes, childNodes[indices[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,8 +146,8 @@ export class ElementPropertyMemento {
|
||||
this._propertyName = propertyName;
|
||||
}
|
||||
|
||||
invoke(record:Record, elementInjectors:List<Element>) {
|
||||
var element:Element = elementInjectors[this._elementIndex];
|
||||
invoke(record:Record, bindElements:List<Element>) {
|
||||
var element:Element = bindElements[this._elementIndex];
|
||||
DOM.setProperty(element, this._propertyName, record.currentValue);
|
||||
}
|
||||
}
|
||||
@ -138,14 +155,13 @@ export class ElementPropertyMemento {
|
||||
export class DirectivePropertyMemento {
|
||||
@FIELD('final _elementInjectorIndex:int')
|
||||
@FIELD('final _directiveIndex:int')
|
||||
@FIELD('final _setterName:String')
|
||||
@FIELD('final _setterName:string')
|
||||
@FIELD('final _setter:SetterFn')
|
||||
constructor(
|
||||
elementInjectorIndex:number,
|
||||
directiveIndex:number,
|
||||
setterName:String,
|
||||
setter:SetterFn)
|
||||
{
|
||||
setterName:string,
|
||||
setter:SetterFn) {
|
||||
this._elementInjectorIndex = elementInjectorIndex;
|
||||
this._directiveIndex = directiveIndex;
|
||||
this._setterName = setterName;
|
||||
@ -154,7 +170,7 @@ export class DirectivePropertyMemento {
|
||||
|
||||
invoke(record:Record, elementInjectors:List<ElementInjector>) {
|
||||
var elementInjector:ElementInjector = elementInjectors[this._elementInjectorIndex];
|
||||
var directive = elementInjectors[this._directiveIndex];
|
||||
var directive = elementInjector.getAtIndex(this._directiveIndex);
|
||||
this._setter(directive, record.currentValue);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user