Jak*_*cas 71 javascript angular
我一直在玩弄角2在过去的几天,不知道是否有可能提供一个动态templateUrl
的@View
装饰.
我试过传递一个函数并返回一个字符串形式,但整个函数只是变成了一个字符串.
我之前没有真正使用过Angular 1.x所以我不知道我是否只是以错误的方式解决这个问题,但是这有可能,还是有更好的方法来创建动态视图?
例如,如果用户未登录,我可能希望显示表单,但如果他们已登录则显示文本消息.
这样的东西不起作用:
@Component({
selector: 'my-component'
})
@View({
// This doesn't work
templateUrl: function() {
return this.isLoggedIn ? 'logged-in.html' : 'logged-out.html';
}
})
class MyComponent {
constructor() {
this.loggedIn = false;
}
}
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激.
Tom*_*omG 23
虽然可能不是最优雅的解决方案,但我使用DynamicComponentLoader和ElementRef动态地将模板值分配给组件.事实上,我一直在寻找一个解决方案,我可以将多个自定义组件添加到占位符中.
我在函数中尝试了服务注入,如shmck所述,这不起作用,因为调用模板函数时服务还不可用.的确,this
指的是Window对象.
我使用的解决方案的参考URL可以在以下位置找到:使用ComponentResolver和Angular2中的ngFor创建动态anchorName/Components
Dartdocs网站提供了有关Angular 2 DynamicComponentLoader类的精彩文档,也适用于TypeScript.
简而言之:
一个简单的Component作为要使用的模板
@Component({
selector: 'dt2-simple-block',
properties: ["idx"],
template: `<h1>Simple block for {{ idx }} </h1>`,
directives: []
})
class dt2SimpleBlock {
constructor() {
}
}
Run Code Online (Sandbox Code Playgroud)
包含要添加的所有组件的Component的构造函数(我的应用程序需要包含多个子项:
constructor(loader: DynamicComponentLoader, elementRef: ElementRef) {
//iterate
for (var i = 0; i < toSomething; i++) {
// build the template
var blockdirective = 'dt2-simple-block'
var template = '<' + blockdirective +
' idx="' + this.userBlocks.userHomePanelBlocks[i] +
'"></' + blockdirective + '>';
console.log(template); // debugging purpose
var directives = [dt2SimpleBlock];
loader.loadNextToLocation(toComponent(template, directives), elementRef);
}
Run Code Online (Sandbox Code Playgroud)
并将辅助函数放在某个地方作为util
function toComponent(template, directives = []) {
@Component({ selector: 'fake-component' })
@View({ template, directives })
class FakeComponent { }
return FakeComponent;
}
Run Code Online (Sandbox Code Playgroud)
小智 11
我的解决方案
class myViewResolver extends ViewResolver{
resolve(component: Type): ViewMetadata {
var view = super.resolve(component);
// TODO: Write logic here:-)
view.templateUrl = 'app/app.html';
return view;
}
}
bootstrap(App,[
provide(ViewResolver , {useClass:myViewResolver})
]);
Run Code Online (Sandbox Code Playgroud)
Yoa*_*oni 10
不是你要求的,但值得一提的是:
另一个适用于大多数用例的简单解决方案是将逻辑放在模板本身中,如下所示:
@Component({
selector: 'my-component'
})
@View({
// Note1: Here, I use template instead of templateUrl.
// Note2: I use ES6 string interpolation + require() to embed/load the other templates, but you can do it however you like.
template: `
<div [ngSwitch]="loggedIn">
<template [ngSwitchCase]="true"> ${require('./logged-in.html')} </template>
<template ngSwitchDefault> ${require('./logged-out.html')} </template>
</div>`
})
class MyComponent {
constructor() {
this.loggedIn = false;
}
}
Run Code Online (Sandbox Code Playgroud)
此解决方案的缺点是您提供的服务js文件最终包含两个模板,因此这可能是大模板的问题(但实际上只渲染了一个模板,并且在许多情况下js大小开销是可接受的).
我的解决方案:(关于这个的美丽是对HTML和CSS文件的延迟加载.)
这是home.componenet.ts
import { Component } from '@angular/core';
import { DynamicHTMLOutlet } from './../../directives/dynamic-html-outlet/dynamicHtmlOutlet.directive';
import { TranslateService, LangChangeEvent } from 'ng2-translate/ng2-translate';
@Component({
selector: 'lib-home',
templateUrl: './app/content/home/home.component.html',
directives: [DynamicHTMLOutlet]
})
export class HomeComponent {
html_template = `./app/content/home/home_`;
html: string;
css: string;
constructor(translate: TranslateService) {
this.html = this.html_template + translate.currentLang;
this.css = './app/content/home/home.component.css';
translate.onLangChange.subscribe((event: LangChangeEvent) => {
this.html = this.html_template + translate.currentLang;
this.css = './app/content/home/home.component.css';
});
}
}
Run Code Online (Sandbox Code Playgroud)
我使用的指令并做了一些更改:这是在home.componenet.html中
<dynamic-html-outlet [htmlPath]="html" [cssPath]="css"></dynamic-html-outlet>
Run Code Online (Sandbox Code Playgroud)
这是动态组件的指令:
import {
Component,
Directive,
ComponentFactory,
ComponentMetadata,
ComponentResolver,
Input,
ReflectiveInjector,
ViewContainerRef,
} from '@angular/core';
import { TranslatePipe } from 'ng2-translate/ng2-translate';
declare var $:any;
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() htmlPath: string;
@Input() cssPath: string;
constructor(private vcRef: ViewContainerRef, private resolver: ComponentResolver) {
}
ngOnChanges() {
if (!this.htmlPath) return;
$('dynamic-html') && $('dynamic-html').remove();
const metadata = new ComponentMetadata({
selector: 'dynamic-html',
templateUrl: this.htmlPath +'.html',
styleUrls: [this.cssPath],
pipes: [TranslatePipe]
});
createComponentFactory(this.resolver, metadata)
.then(factory => {
const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
this.vcRef.createComponent(factory, 0, injector, []);
});
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
60873 次 |
最近记录: |