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); ListWrapper.map(allDirectives, directiveBinding => directiveBinding.metadata);
var nestedPvsWithIndex = _collectNestedProtoViews(rootRenderProtoView); var nestedPvsWithIndex = _collectNestedProtoViews(rootRenderProtoView);
var nestedPvVariableBindings = _collectNestedProtoViewsVariableBindings(nestedPvsWithIndex); var nestedPvVariableBindings = _collectNestedProtoViewsVariableBindings(nestedPvsWithIndex);
var nestedPvVariableNames = var nestedPvVariableNames = _collectNestedProtoViewsVariableNames(nestedPvsWithIndex);
_collectNestedProtoViewsVariableNames(nestedPvsWithIndex, nestedPvVariableBindings);
var changeDetectorDefs = var changeDetectorDefs =
_getChangeDetectorDefinitions(hostComponentBinding.metadata, nestedPvsWithIndex, _getChangeDetectorDefinitions(hostComponentBinding.metadata, nestedPvsWithIndex,
nestedPvVariableNames, allRenderDirectiveMetadata); nestedPvVariableNames, allRenderDirectiveMetadata);
@ -174,10 +174,7 @@ export function getChangeDetectorDefinitions(
hostComponentMetadata: renderApi.DirectiveMetadata, rootRenderProtoView: renderApi.ProtoViewDto, hostComponentMetadata: renderApi.DirectiveMetadata, rootRenderProtoView: renderApi.ProtoViewDto,
allRenderDirectiveMetadata: List<renderApi.DirectiveMetadata>): List<ChangeDetectorDefinition> { allRenderDirectiveMetadata: List<renderApi.DirectiveMetadata>): List<ChangeDetectorDefinition> {
var nestedPvsWithIndex = _collectNestedProtoViews(rootRenderProtoView); var nestedPvsWithIndex = _collectNestedProtoViews(rootRenderProtoView);
var nestedPvVariableBindings = _collectNestedProtoViewsVariableBindings(nestedPvsWithIndex); var nestedPvVariableNames = _collectNestedProtoViewsVariableNames(nestedPvsWithIndex);
var nestedPvVariableNames =
_collectNestedProtoViewsVariableNames(nestedPvsWithIndex, nestedPvVariableBindings);
return _getChangeDetectorDefinitions(hostComponentMetadata, nestedPvsWithIndex, return _getChangeDetectorDefinitions(hostComponentMetadata, nestedPvsWithIndex,
nestedPvVariableNames, allRenderDirectiveMetadata); nestedPvVariableNames, allRenderDirectiveMetadata);
} }
@ -235,8 +232,6 @@ function _createAppProtoView(
variableBindings: Map<string, string>, allDirectives: List<DirectiveBinding>): AppProtoView { variableBindings: Map<string, string>, allDirectives: List<DirectiveBinding>): AppProtoView {
var elementBinders = renderProtoView.elementBinders; var elementBinders = renderProtoView.elementBinders;
var protoView = new AppProtoView(renderProtoView.render, protoChangeDetector, variableBindings); var protoView = new AppProtoView(renderProtoView.render, protoChangeDetector, variableBindings);
// TODO: vsavkin refactor to pass element binders into proto view
_createElementBinders(protoView, elementBinders, allDirectives); _createElementBinders(protoView, elementBinders, allDirectives);
_bindDirectiveEvents(protoView, elementBinders); _bindDirectiveEvents(protoView, elementBinders);
@ -255,31 +250,30 @@ function _createVariableBindings(renderProtoView): Map<string, string> {
MapWrapper.forEach(renderProtoView.variableBindings, (mappedName, varName) => { MapWrapper.forEach(renderProtoView.variableBindings, (mappedName, varName) => {
MapWrapper.set(variableBindings, varName, mappedName); MapWrapper.set(variableBindings, varName, mappedName);
}); });
ListWrapper.forEach(renderProtoView.elementBinders, binder => {
MapWrapper.forEach(binder.variableBindings, (mappedName, varName) => {
MapWrapper.set(variableBindings, varName, mappedName);
});
});
return variableBindings; return variableBindings;
} }
function _collectNestedProtoViewsVariableNames( function _collectNestedProtoViewsVariableNames(
nestedPvsWithIndex: List<RenderProtoViewWithIndex>, nestedPvsWithIndex: List<RenderProtoViewWithIndex>): List<List<string>> {
nestedPvVariableBindings: List<Map<string, string>>): List<List<string>> {
var nestedPvVariableNames = ListWrapper.createFixedSize(nestedPvsWithIndex.length); var nestedPvVariableNames = ListWrapper.createFixedSize(nestedPvsWithIndex.length);
ListWrapper.forEach(nestedPvsWithIndex, (pvWithIndex) => { ListWrapper.forEach(nestedPvsWithIndex, (pvWithIndex) => {
var parentVariableNames = var parentVariableNames =
isPresent(pvWithIndex.parentIndex) ? nestedPvVariableNames[pvWithIndex.parentIndex] : null; isPresent(pvWithIndex.parentIndex) ? nestedPvVariableNames[pvWithIndex.parentIndex] : null;
nestedPvVariableNames[pvWithIndex.index] = nestedPvVariableNames[pvWithIndex.index] =
_createVariableNames(parentVariableNames, nestedPvVariableBindings[pvWithIndex.index]); _createVariableNames(parentVariableNames, pvWithIndex.renderProtoView);
}); });
return nestedPvVariableNames; return nestedPvVariableNames;
} }
function _createVariableNames(parentVariableNames, variableBindings): List<string> {
var variableNames = isPresent(parentVariableNames) ? ListWrapper.clone(parentVariableNames) : []; function _createVariableNames(parentVariableNames, renderProtoView): List<string> {
MapWrapper.forEach(variableBindings, (local, v) => { ListWrapper.push(variableNames, local); }); var res = isBlank(parentVariableNames) ? [] : ListWrapper.clone(parentVariableNames);
return variableNames; 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) { 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).not.toBe(null);
expect(view.rawView.locals.get('superAlice')).toBeAnInstanceOf(ChildComp); 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(); 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'}) @Component({selector: 'child-cmp-svc'})
@View({template: '{{ctxProp}}'}) @View({template: '{{ctxProp}}'})
@Injectable() @Injectable()