我正在尝试创建一个组件,其中包含一个动态模板字符串,可以访问模板上的局部变量。我尝试过的每种方法最终都是“动态模板字符串”,而不是$compile
'd(角度1术语,请原谅)。
以下是该组件的代码。在您看到评论的位置我想插入一个可以在item
中引用ngFor
的模板字符串。
@Component({
selector: 'ion-alpha-scroll',
template: `
<ion-scroll [ngStyle]="calculateScrollHeight()" scrollX="false" scrollY="true">
<ion-list class="ion-alpha-list-outer">
<div *ngFor="let items of sortedItems | mapToIterable;">
<ion-item-divider id="scroll-letter-{{items.key}}">{{items.key}}</ion-item-divider>
<ion-item *ngFor="let item of items.value">
<!-- how can I pass a dynamic template here that can reference item ? -->
</ion-item>
</div>
</ion-list>
</ion-scroll>
<ul class="ion-alpha-sidebar" [ngStyle]="calculateDimensionsForSidebar()">
<li (click)="alphaScrollGoToList(letter)" *ngFor="let letter of alphabet">
<div class="letter">{{letter}}</div>
</li>
</ul>
`,
pipes: [MapToIterable]
})
export class IonAlphaScroll {
@Input() listData: any;
@Input() key: string;
@Input() template: string;
....
}
理想情况下,我希望在ion-alpha-scroll
中将item
引用的ngFor
引用为ng-content
。我尝试在组件的必要ngFor
中使用<ion-alpha-scroll *ngIf="breeds" [listData]="breeds" key="$t">
{{item.$t}}
</ion-alpha-scroll>
并且没有运气 -
<ion-alpha-scroll *ngIf="breeds" [listData]="breeds" key="$t" [template]="alphaScrollTemplate">
</ion-alpha-scroll>
我试过的一件事就是这样 -
alphaScrollTemplate
{{item.$t}}
只是一个包含...
<ion-item *ngFor="let item of items.value">
{{template}}
<!-- this just outputs {{item.$t}} literally -->
</ion-item>
...
的字符串。然后我尝试在评论提出问题的组件中引用它,但它不起作用 -
rootRef.addListenerForSingleValueEvent()
我真的很好奇,如果角度2还可以。我刚刚找到this question which is very similar to mine。任何帮助或建议将不胜感激,谢谢。
答案 0 :(得分:0)
这是我用于角度2.0.0-rc.3的解决方案
此解决方案创建了一个动态组件,并使用ViewContainerRef
和ComponentFactory
加载它。 Here is the ionic 2 component on GitHub
export function createComponentFactory(resolver: ComponentResolver, metadata: ComponentMetadata): Promise<ComponentFactory<any>> {
const cmpClass = class DynamicComponent {};
const decoratedCmp = Component(metadata)(cmpClass);
return resolver.resolveComponent(decoratedCmp);
}
@Directive({
selector: 'dynamic-html-outlet',
})
export class DynamicHTMLOutlet {
@Input() src: string;
@Input() ionAlphaScrollRef: any;
@Input() currentPageClass: any;
constructor(private vcRef: ViewContainerRef, private resolver: ComponentResolver) {
}
ngOnChanges() {
if (!this.src) return;
const metadata = new ComponentMetadata({
selector: 'dynamic-html',
template: this.src,
pipes: [MapToIterable]
});
createComponentFactory(this.resolver, metadata).then(factory => {
const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
let component = this.vcRef.createComponent(factory, 0, injector, []);
component.instance.ionAlphaScrollRef = this.ionAlphaScrollRef;
component.instance.currentPageClass = this.currentPageClass;
});
}
}
@Component({
selector: 'ion-alpha-scroll',
template: `
<dynamic-html-outlet
[src]="alphaScrollTemplate"
[ionAlphaScrollRef]="ionAlphaScrollRef"
[currentPageClass]="currentPageClass">
</dynamic-html-outlet>
`,
pipes: [MapToIterable],
directives: [DynamicHTMLOutlet]
})
export class IonAlphaScroll {
@Input() listData: any;
@Input() key: string;
@Input() itemTemplate: string;
@Input() currentPageClass: any;
@Input() triggerChange: any;
private _scrollEle: HTMLElement;
sortedItems: any = {};
alphabet: any = [];
alphaScrollTemplate: string;
ionAlphaScrollRef = this;
constructor(
@Host() private _content: Content,
private _elementRef: ElementRef,
private vcRef: ViewContainerRef,
private resolver: ComponentResolver
) {
}
ngOnInit() {
this.alphaScrollTemplate = `
<style>
.ion-alpha-sidebar {
position: fixed;
right: 0;
display: flex;
flex-flow: column;
z-index: 50000;
}
.ion-alpha-sidebar li {
flex: 1 1 auto;
list-style: none;
width: 15px;
text-align: center;
}
</style>
<ion-scroll class="ion-alpha-scroll" [ngStyle]="ionAlphaScrollRef.calculateScrollDimensions()" scrollX="false" scrollY="true">
<ion-list class="ion-alpha-list-outer">
<div *ngFor="let items of ionAlphaScrollRef.sortedItems | mapToIterable; trackBy:ionAlphaScrollRef.trackBySortedItems">
<ion-item-divider id="scroll-letter-{{items.key}}">{{items.key}}</ion-item-divider>
<ion-item *ngFor="let item of items.value">
${this.itemTemplate}
</ion-item>
</div>
</ion-list>
</ion-scroll>
<ul class="ion-alpha-sidebar" [ngStyle]="ionAlphaScrollRef.calculateDimensionsForSidebar()">
<li *ngFor="let letter of ionAlphaScrollRef.alphabet" tappable (click)="ionAlphaScrollRef.alphaScrollGoToList(letter)">
<a>{{letter}}</a>
</li>
</ul>
`;
setTimeout(() => {
this._scrollEle = this._elementRef.nativeElement.querySelector('scroll-content');
this.setupHammerHandlers();
});
}
ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
let tmp = {};
for (let i = 0; i < this.listData.length; i++) {
let letter = this.listData[i][this.key].toUpperCase().charAt(0);
if (typeof tmp[letter] === 'undefined') {
tmp[letter] = [];
}
tmp[letter].push(this.listData[i]);
}
this.alphabet = this.iterateAlphabet(tmp);
this.sortedItems = tmp;
}
// ....
}