我在Angular2 rc 1中有一个模板,我需要在其中显示来自不同语言的一大块代码。该语言有{{in it。
import {Component, Input} from '@angular/core';
@Component({
selector: 'blue-box',
template: `
<div class="blue-box">
<div class="blue-box-title">{{boxTitle}}</div>
{{define "bob"}}This is the template bob{{end}}
<span>
<ng-content></ng-content>
</span>
</div>
`,
styleUrls: ['../css/blue-box.css'],
})
export class BlueBox {
@Input() boxTitle: string;
constructor() {
}
}
如何让模板处理器将{{作为文字字符串而不是模板表达式的开头?出现问题 在{{define“bob”}},我需要一个文字{{。
浏览器(chrome)控制台上的错误是:
EXCEPTION: Template parse errors:
Parser Error: Unexpected token 'bob' at column 8 in [
{{define "bob"}}This is the template bob{{end}}
] in BlueBox@2:49 ("
<div class="blue-box">
<div class="blue-box-title">{{boxTitle}}</div>[ERROR ->]
{{define "bob"}}This is the template bob{{end}}
<span>
<ng-content></ng-content>
"): BlueBox@2:49
答案 0 :(得分:12)
使用 ngNonBindable
示例:
<div ngNonBindable> {{ I'm inside curly bracket }} </div>
<强>更新强>
以上内容在Anuglar 2中有效,现在在Angular 4中有一个名为DomSanitizer
的类,可用于在HTML中插入任何类型的代码作为文本。
您可以从plunker
查看此工作micronyks's answer答案 1 :(得分:1)
ngNonBindable - 并不总是一个选项,你必须使用额外的DOM元素,实际上有更好的方法
在下一个版本中,将有一种方法可以自定义插值regexp https://github.com/angular/angular/pull/7417#issuecomment-221761034。它已经合并,将在下一个版本中提供。
现在你可以这样做。转到main.ts(或其他您执行引导程序的文件)并添加此
// some of your imports here
import { Provider } from '@angular/core';
import { Parser, SplitInterpolation } from '@angular/compiler/src/expression_parser/parser';
import { Lexer } from '@angular/compiler/src/expression_parser/lexer';
import { StringWrapper } from '@angular/platform-browser/src/facade/lang';
import { BaseException } from '@angular/platform-browser/src/facade/exceptions';
class Parser2 extends Parser {
myInterpolationRegexp = /\[\[([\s\S]*?)\]\]/g; // <- CUSTOMIZATION
constructor(public _lexer: Lexer) {
super(_lexer)
}
splitInterpolation(input, location):SplitInterpolation {
var parts = StringWrapper.split(input, this.myInterpolationRegexp);
if (parts.length <= 1) {
return null;
}
var strings = [];
var expressions = [];
for (var i = 0; i < parts.length; i++) {
var part: string = parts[i];
if (i % 2 === 0) {
// fixed string
strings.push(part);
} else if (part.trim().length > 0) {
expressions.push(part);
} else {
var exs = `Parser Error: Blank expressions are not allowed in interpolated strings at column ${this._findInterpolationErrorColumn2(parts, i)} in [${input}] in ${location}`;
throw new BaseException(exs);
}
}
return new SplitInterpolation(strings, expressions);
}
private _findInterpolationErrorColumn2(parts: string[], partInErrIdx: number): number {
var errLocation = '';
for (var j = 0; j < partInErrIdx; j++) {
errLocation += j % 2 === 0 ? parts[j] : `{{${parts[j]}}}`;
}
return errLocation.length;
}
}
bootstrap(AppComponent, [
// add your custom providers array with out parser provider
new Provider(Parser, { useClass: Parser2 })
]);
现在您可以像这样编写模板
<div>[[ title ]]</div>
{{begin}} asdas {{#end}}
<div>
<div *ngFor="let item of list | isodd">
[[ item.name ]]
</div>
</div>
请注意,现在您不必将代码包装在NgNonBindable
中UPD:
这个例子将以可能的方式打破
<div>{{ title }}</div>
<div ngNonBindable>
{{begin}}
<button (click)="add()">add</button> <!--- Will Explode!!! --->
<div>
<div *ngFor="let item of list | isodd">
{{ item.name }}
</div>
</div>
{{#end}}
</div>
如果你使用InterpolationRegexp - 一切都会正常工作(而且它的DIV就更少了)
<div>[[ title ]]</div>
{{begin}}
<button (click)="add()">add</button>
<div>
<div *ngFor="let item of list | isodd">
[[ item.name ]]
</div>
</div>
{{#end}}