typescript 将 HTML 文件读入 Angular 2 中的模板?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37123514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read HTML File into template in Angular 2?
提问by EMChamp
I'm trying to create dynamic modals in Angular 2 using the ng2-bs3-modals. I would like to fill in the modal html body text dynamically based on the parameter passed to the selector used in the main component's view. When I use this code however it seems to treat my entire function as text and so my modal displays the code of my 'function determineModalContent' rather than the intended behavior which is to display the contents of the file.
我正在尝试使用 ng2-bs3-modals 在 Angular 2 中创建动态模态。我想根据传递给主组件视图中使用的选择器的参数动态填充模态 html 正文文本。然而,当我使用此代码时,它似乎将我的整个函数视为文本,因此我的模式显示了我的“函数确定模态内容”的代码,而不是显示文件内容的预期行为。
I also know that my code won't return the contents of the file, just the string but I haven't yet figured out how in Angular2/TypeScript to read in the file contents.
我也知道我的代码不会返回文件的内容,只是字符串,但我还没有弄清楚如何在 Angular2/TypeScript 中读取文件内容。
import { Component, Input } from 'angular2/core'
@Component({
selector: 'static-modal',
template: '{{modalBody}}'
})
export class StaticModalComponent {
@Input() modalID;
template = 'app/shared/modals/static-message-1.html'
modalBody = function determineModalContent(modalID){
if(modalID == "1")
return 'app/shared/modals/static-message-1.html';
else if(modalID == "2")
return 'app/shared/modals/static-message-2.html';
else
return 'app/shared/modals/static-message-default.html';
}
}
回答by S.Klechkovski
What you need here is something like ng-includeI suppose. And as you can see in this issueon the Angular repo, most probably we won't get that directive. There has been a long discussion whether we need this directive or not, and if not provided how we can implement it by our self.
我想你在这里需要的是ng-include 之类的东西。正如你在 Angular 存储库的这个issue 中看到的,我们很可能不会得到那个指令。对于我们是否需要这个指令,以及如果没有提供我们如何自己实现它,已经进行了很长时间的讨论。
I tried to make a simple example of how it can be implemented.
我试图举一个简单的例子来说明它是如何实现的。
@Component({
selector: 'my-ng-include',
template: '<div #myNgIncludeContent></div>'
})
export class MyNgInclude implements OnInit {
@Input('src')
private templateUrl: string;
@ViewChild('myNgIncludeContent', { read: ViewContainerRef })
protected contentTarget: ViewContainerRef;
constructor(private componentResolver: ComponentResolver) {}
ngOnInit() {
var dynamicComponent = this.createContentComponent(this.templateUrl);
this.componentResolver.resolveComponent(dynamicComponent)
.then((factory: any) => this.contentTarget.createComponent(factory));
}
createContentComponent(templateUrl) {
@Component({
selector: 'my-ng-include-content',
templateUrl: templateUrl,
directives: FORM_DIRECTIVES,
})
class MyNgIncludeContent {}
return MyNgIncludeContent ;
}
}
For a demo check this Plunker.
对于演示,请检查这个Plunker。
回答by Tim Consolazio
It may be maligned as "verboten" for a number of reasons that I understand, including the underscore you will see, but this works. Fact is I have a need to do this very simply and I don't want to (nor should I have to) write a lot of code to do it. I can scrub the HTML etc. I get if this is more helpful than an answer but some may find it useful.
由于我理解的多种原因,包括您将看到的下划线,它可能会被诽谤为“verboten”,但这是有效的。事实是我需要非常简单地执行此操作,并且我不想(也不应该)编写大量代码来执行此操作。我可以清理 HTML 等。如果这比答案更有帮助,我会明白,但有些人可能会觉得它很有用。
In the component API (ES6 style), declare a queries entry (or otherwise create your ViewChild using TS), this should map to an element with a template reference variable and so on. Note that using the queries part of the component API as I show here works fine in TS:
在组件 API(ES6 样式)中,声明一个查询条目(或以其他方式使用 TS 创建您的 ViewChild),这应该映射到具有模板引用变量等的元素。请注意,使用我在此处展示的组件 API 的查询部分在 TS 中工作正常:
// Assumes you have <div #targetdiv></div> in your component template
queries: {
targetDivRef : new ViewChild ( 'targetdiv' )
}
Then in some click handler, onInit or whatever (keeping in mind not to try this too early in the comp lifecycle) get the page you want async, and just dump the contents into the div.
然后在一些单击处理程序中,onInit 或其他任何(记住不要在 comp 生命周期中过早尝试)获取您想要异步的页面,然后将内容转储到 div 中。
let elem = this.targetDivRef.nativeElement;
let svc = this.http.get ( './thepage.html' )
.map ( response => { return response [ '_body' ] } );
svc.subscribe (
( x ) => { elem.innerHTML = x },
( err ) => console.log ( err ),
( ) => console.log ( 'Complete' )
)
Again, almost surely not "recommended". But it's simple and it works. You actually don't even need the subscribe, you can just set the val in the map func, this is just more complete etc.
同样,几乎可以肯定不是“推荐”。但它很简单而且有效。您实际上甚至不需要订阅,您只需在 map func 中设置 val,这只是更完整等。
When we get an option similar to ng-include (which IMHO is a glaring ommission), or an otherwise three-line option to do this, I'll make the switch. Handle request errors etc. as you see fit.
当我们得到一个类似于 ng-include 的选项(恕我直言,这是一个明显的遗漏),或者其他三行选项来执行此操作时,我将进行切换。根据您的需要处理请求错误等。
回答by Maxime Bouveron
If the templates aren't that different, you can just add all your different bodies in the same html file and choose which one is displayed with the *ngIf
directive :
如果模板没有什么不同,您可以将所有不同的主体添加到同一个 html 文件中,然后选择使用*ngIf
指令显示的主体:
<modal>
<modal-header>
<h4 class="modal-title">Title</h4>
</modal-header>
<modal-body>
<div *ngIf='modalID == "1"'>
content1
</div>
<div *ngIf='modalID == "2"'>
content2
</div>
<div *ngIf='modalID != "1" && modalID != "2"'>
content3
</div>
</modal-body>
<modal-footer [show-default-buttons]="true"></modal-footer>
</modal>