fix(view): local variables override local variables set by ng-for

This commit is contained in:
vsavkin 2015-06-15 18:05:29 -07:00
parent 7a41b19e58
commit d8e2795368
2 changed files with 39 additions and 20 deletions

View File

@ -143,8 +143,8 @@ export class ProtoViewFactory {
ListWrapper.map(allDirectives, directiveBinding => directiveBinding.metadata);
var nestedPvsWithIndex = _collectNestedProtoViews(rootRenderProtoView);
var nestedPvVariableBindings = _collectNestedProtoViewsVariableBindings(nestedPvsWithIndex);
var nestedPvVariableNames =
_collectNestedProtoViewsVariableNames(nestedPvsWithIndex, nestedPvVariableBindings);
var nestedPvVariableNames = _collectNestedProtoViewsVariableNames(nestedPvsWithIndex);
var changeDetectorDefs =
_getChangeDetectorDefinitions(hostComponentBinding.metadata, nestedPvsWithIndex,
nestedPvVariableNames, allRenderDirectiveMetadata);
@ -174,10 +174,7 @@ export function getChangeDetectorDefinitions(
hostComponentMetadata: renderApi.DirectiveMetadata, rootRenderProtoView: renderApi.ProtoViewDto,
allRenderDirectiveMetadata: List<renderApi.DirectiveMetadata>): List<ChangeDetectorDefinition> {
var nestedPvsWithIndex = _collectNestedProtoViews(rootRenderProtoView);
var nestedPvVariableBindings = _collectNestedProtoViewsVariableBindings(nestedPvsWithIndex);
var nestedPvVariableNames =
_collectNestedProtoViewsVariableNames(nestedPvsWithIndex, nestedPvVariableBindings);
var nestedPvVariableNames = _collectNestedProtoViewsVariableNames(nestedPvsWithIndex);
return _getChangeDetectorDefinitions(hostComponentMetadata, nestedPvsWithIndex,
nestedPvVariableNames, allRenderDirectiveMetadata);
}
@ -235,8 +232,6 @@ function _createAppProtoView(
variableBindings: Map<string, string>, allDirectives: List<DirectiveBinding>): AppProtoView {
var elementBinders = renderProtoView.elementBinders;
var protoView = new AppProtoView(renderProtoView.render, protoChangeDetector, variableBindings);
// TODO: vsavkin refactor to pass element binders into proto view
_createElementBinders(protoView, elementBinders, allDirectives);
_bindDirectiveEvents(protoView, elementBinders);
@ -255,31 +250,30 @@ function _createVariableBindings(renderProtoView): Map<string, string> {
MapWrapper.forEach(renderProtoView.variableBindings, (mappedName, varName) => {
MapWrapper.set(variableBindings, varName, mappedName);
});
ListWrapper.forEach(renderProtoView.elementBinders, binder => {
MapWrapper.forEach(binder.variableBindings, (mappedName, varName) => {
MapWrapper.set(variableBindings, varName, mappedName);
});
});
return variableBindings;
}
function _collectNestedProtoViewsVariableNames(
nestedPvsWithIndex: List<RenderProtoViewWithIndex>,
nestedPvVariableBindings: List<Map<string, string>>): List<List<string>> {
nestedPvsWithIndex: List<RenderProtoViewWithIndex>): List<List<string>> {
var nestedPvVariableNames = ListWrapper.createFixedSize(nestedPvsWithIndex.length);
ListWrapper.forEach(nestedPvsWithIndex, (pvWithIndex) => {
var parentVariableNames =
isPresent(pvWithIndex.parentIndex) ? nestedPvVariableNames[pvWithIndex.parentIndex] : null;
nestedPvVariableNames[pvWithIndex.index] =
_createVariableNames(parentVariableNames, nestedPvVariableBindings[pvWithIndex.index]);
_createVariableNames(parentVariableNames, pvWithIndex.renderProtoView);
});
return nestedPvVariableNames;
}
function _createVariableNames(parentVariableNames, variableBindings): List<string> {
var variableNames = isPresent(parentVariableNames) ? ListWrapper.clone(parentVariableNames) : [];
MapWrapper.forEach(variableBindings, (local, v) => { ListWrapper.push(variableNames, local); });
return variableNames;
function _createVariableNames(parentVariableNames, renderProtoView): List<string> {
var res = isBlank(parentVariableNames) ? [] : ListWrapper.clone(parentVariableNames);
MapWrapper.forEach(renderProtoView.variableBindings,
(mappedName, varName) => { res.push(mappedName); });
ListWrapper.forEach(renderProtoView.elementBinders, binder => {
MapWrapper.forEach(binder.variableBindings, (mappedName, varName) => { res.push(mappedName); });
});
return res;
}
function _createElementBinders(protoView, elementBinders, allDirectiveBindings) {

View File

@ -541,6 +541,24 @@ export function main() {
expect(view.rawView.locals).not.toBe(null);
expect(view.rawView.locals.get('superAlice')).toBeAnInstanceOf(ChildComp);
async.done();
});
}));
it('should allow to use variables in a for loop',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
tb.overrideView(MyComp, new viewAnn.View({
template:
'<div><div *ng-for="var i of [1]"><child-cmp-no-template #cmp></child-cmp-no-template>{{i}}-{{cmp.ctxProp}}</div></div>',
directives: [ChildCompNoTemplate, NgFor]
}));
tb.createView(MyComp, {context: ctx})
.then((view) => {
view.detectChanges();
expect(view.rootNodes).toHaveText("1-hello");
async.done();
});
}));
@ -1343,6 +1361,13 @@ class ChildComp {
}
}
@Component({selector: 'child-cmp-no-template'})
@View({directives: [], template: ''})
@Injectable()
class ChildCompNoTemplate {
ctxProp: string = 'hello';
}
@Component({selector: 'child-cmp-svc'})
@View({template: '{{ctxProp}}'})
@Injectable()