@@ -421,7 +421,7 @@ class _Context {
421421
422422export class ElementInjector extends TreeNode < ElementInjector > implements DependencyProvider {
423423 private _host : ElementInjector ;
424- private _preBuiltObjects = null ;
424+ private _preBuiltObjects : PreBuiltObjects = null ;
425425
426426 // Queries are added during construction or linking with a new parent.
427427 // They are removed only through unlinking.
@@ -477,19 +477,35 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
477477 this . _host = host ;
478478 this . _preBuiltObjects = preBuiltObjects ;
479479
480- this . _reattachInjectors ( imperativelyCreatedInjector ) ;
481- this . _strategy . hydrate ( ) ;
482-
483480 if ( isPresent ( host ) ) {
484481 this . _addViewQueries ( host ) ;
485482 }
486483
484+ this . _reattachInjectors ( imperativelyCreatedInjector ) ;
485+ this . _strategy . hydrate ( ) ;
486+
487487 this . _addDirectivesToQueries ( ) ;
488488 this . _addVarBindingsToQueries ( ) ;
489489
490+ // TODO(rado): optimize this call, if view queries are not moved around,
491+ // simply appending to the query list is faster than updating.
492+ this . _updateViewQueries ( ) ;
493+
490494 this . hydrated = true ;
491495 }
492496
497+ private _updateViewQueries ( ) {
498+ if ( isPresent ( this . _query0 ) && this . _query0 . isViewQuery ) {
499+ this . _query0 . update ( ) ;
500+ }
501+ if ( isPresent ( this . _query1 ) && this . _query1 . isViewQuery ) {
502+ this . _query1 . update ( ) ;
503+ }
504+ if ( isPresent ( this . _query2 ) && this . _query2 . isViewQuery ) {
505+ this . _query2 . update ( ) ;
506+ }
507+ }
508+
493509 private _debugContext ( ) : any {
494510 var p = this . _preBuiltObjects ;
495511 var index = p . elementRef . boundElementIndex - p . view . elementOffset ;
@@ -651,22 +667,19 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
651667 }
652668
653669 private _addViewQueries ( host : ElementInjector ) : void {
654- if ( isPresent ( host . _query0 ) && host . _query0 . originator == host &&
655- host . _query0 . query . isViewQuery )
656- this . _addViewQuery ( host . _query0 ) ;
657- if ( isPresent ( host . _query1 ) && host . _query1 . originator == host &&
658- host . _query1 . query . isViewQuery )
659- this . _addViewQuery ( host . _query1 ) ;
660- if ( isPresent ( host . _query2 ) && host . _query2 . originator == host &&
661- host . _query2 . query . isViewQuery )
662- this . _addViewQuery ( host . _query2 ) ;
663- }
664-
665- private _addViewQuery ( queryRef : QueryRef ) : void {
666- // TODO(rado): Replace this.parent check with distanceToParent = 1 when
667- // https://github.com/angular/angular/issues/2707 is fixed.
668- if ( ! queryRef . query . descendants && isPresent ( this . parent ) ) return ;
669- this . _assignQueryRef ( queryRef ) ;
670+ this . _addViewQuery ( host . _query0 , host ) ;
671+ this . _addViewQuery ( host . _query1 , host ) ;
672+ this . _addViewQuery ( host . _query2 , host ) ;
673+ }
674+
675+ private _addViewQuery ( queryRef : QueryRef , host : ElementInjector ) : void {
676+ if ( isBlank ( queryRef ) || ! queryRef . isViewQuery || this . _hasQuery ( queryRef ) ) return ;
677+ if ( host . _query0 . originator == host ) {
678+ // TODO(rado): Replace this.parent check with distanceToParent = 1 when
679+ // https://github.com/angular/angular/issues/2707 is fixed.
680+ if ( ! queryRef . query . descendants && isPresent ( this . parent ) ) return ;
681+ this . _assignQueryRef ( queryRef ) ;
682+ }
670683 }
671684
672685 private _addVarBindingsToQueries ( ) : void {
@@ -694,6 +707,7 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
694707
695708 private _addDirectivesToQuery ( queryRef : QueryRef ) : void {
696709 if ( isBlank ( queryRef ) || queryRef . query . isVarBindingQuery ) return ;
710+ if ( queryRef . isViewQuery && queryRef . originator == this ) return ;
697711
698712 var matched = [ ] ;
699713 this . addDirectivesMatchingQuery ( queryRef . query , matched ) ;
@@ -754,42 +768,37 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
754768 this . _addParentQueries ( ) ;
755769 }
756770
771+ unlink ( ) : void {
772+ var parent = this . parent ;
773+ this . remove ( ) ;
774+ this . _removeParentQueries ( parent ) ;
775+ }
776+
757777 private _addParentQueries ( ) : void {
758778 if ( isBlank ( this . parent ) ) return ;
759- if ( isPresent ( this . parent . _query0 ) && ! this . parent . _query0 . query . isViewQuery ) {
760- this . _addQueryToTree ( this . parent . _query0 ) ;
761- if ( this . hydrated ) this . parent . _query0 . update ( ) ;
762- }
763- if ( isPresent ( this . parent . _query1 ) && ! this . parent . _query1 . query . isViewQuery ) {
764- this . _addQueryToTree ( this . parent . _query1 ) ;
765- if ( this . hydrated ) this . parent . _query1 . update ( ) ;
766- }
767- if ( isPresent ( this . parent . _query2 ) && ! this . parent . _query2 . query . isViewQuery ) {
768- this . _addQueryToTree ( this . parent . _query2 ) ;
769- if ( this . hydrated ) this . parent . _query2 . update ( ) ;
770- }
779+ this . _addParentQuery ( this . parent . _query0 ) ;
780+ this . _addParentQuery ( this . parent . _query1 ) ;
781+ this . _addParentQuery ( this . parent . _query2 ) ;
771782 }
772783
773- unlink ( ) : void {
774- var queriesToUpdate = [ ] ;
775- if ( isPresent ( this . parent . _query0 ) ) {
776- this . _pruneQueryFromTree ( this . parent . _query0 ) ;
777- queriesToUpdate . push ( this . parent . _query0 ) ;
778- }
779- if ( isPresent ( this . parent . _query1 ) ) {
780- this . _pruneQueryFromTree ( this . parent . _query1 ) ;
781- queriesToUpdate . push ( this . parent . _query1 ) ;
782- }
783- if ( isPresent ( this . parent . _query2 ) ) {
784- this . _pruneQueryFromTree ( this . parent . _query2 ) ;
785- queriesToUpdate . push ( this . parent . _query2 ) ;
784+ private _addParentQuery ( query ) : void {
785+ if ( isPresent ( query ) && ! this . _hasQuery ( query ) ) {
786+ this . _addQueryToTree ( query ) ;
787+ if ( this . hydrated ) query . update ( ) ;
786788 }
789+ }
787790
788- this . remove ( ) ;
789- // TODO(rado): update should work on view queries too, however currently it
790- // is not implemented, so we filter to non-view queries.
791- var nonViewQueries = ListWrapper . filter ( queriesToUpdate , ( q ) => ! q . query . isViewQuery ) ;
792- ListWrapper . forEach ( nonViewQueries , ( q ) => q . update ( ) ) ;
791+ private _removeParentQueries ( parent : ElementInjector ) : void {
792+ this . _removeParentQuery ( parent . _query0 ) ;
793+ this . _removeParentQuery ( parent . _query1 ) ;
794+ this . _removeParentQuery ( parent . _query2 ) ;
795+ }
796+
797+ private _removeParentQuery ( query : QueryRef ) {
798+ if ( isPresent ( query ) ) {
799+ this . _pruneQueryFromTree ( query ) ;
800+ query . update ( ) ;
801+ }
793802 }
794803
795804 private _pruneQueryFromTree ( query : QueryRef ) : void {
@@ -852,6 +861,12 @@ export class ElementInjector extends TreeNode<ElementInjector> implements Depend
852861 getHost ( ) : ElementInjector { return this . _host ; }
853862
854863 getBoundElementIndex ( ) : number { return this . _proto . index ; }
864+
865+ getRootViewInjectors ( ) : ElementInjector [ ] {
866+ var view = this . _preBuiltObjects . view ;
867+ return view . getNestedView ( view . elementOffset + this . getBoundElementIndex ( ) )
868+ . rootElementInjectors ;
869+ }
855870}
856871
857872interface _ElementInjectorStrategy {
@@ -1133,9 +1148,19 @@ export class QueryRef {
11331148 constructor ( public query : Query , public list : QueryList < any > ,
11341149 public originator : ElementInjector ) { }
11351150
1151+ get isViewQuery ( ) : boolean { return this . query . isViewQuery ; }
1152+
11361153 update ( ) : void {
11371154 var aggregator = [ ] ;
1138- this . visit ( this . originator , aggregator ) ;
1155+ if ( this . query . isViewQuery ) {
1156+ // intentionally skipping originator for view queries.
1157+ var rootViewInjectors = this . originator . getRootViewInjectors ( ) ;
1158+ for ( var i = 0 ; i < rootViewInjectors . length ; i ++ ) {
1159+ this . visit ( rootViewInjectors [ i ] , aggregator ) ;
1160+ }
1161+ } else {
1162+ this . visit ( this . originator , aggregator ) ;
1163+ }
11391164 this . list . reset ( aggregator ) ;
11401165 }
11411166
0 commit comments