如何在 html 元素属性中使用 Angular 2 外推?
Posted
技术标签:
【中文标题】如何在 html 元素属性中使用 Angular 2 外推?【英文标题】:How to use Angular 2 extrapolation in html element attributes? 【发布时间】:2016-07-06 02:15:07 【问题描述】:我想将一些数据绑定到非自定义的 html 元素属性。但是,属性中的 不是外推的。 我将其他相关帖子视为“Angularjs templateUrl fails to bind attributes inside ng-repeat”,这是自定义指令的 angular 1 解决方案。
例如,我有:
size = 500;
我希望以下 SVG 元素正常工作:
<svg xmlns="http://www.w3.org/2000/svg/" >
<rect fill="#DCB35C"/>
</svg>
我应该如何在 Angular 2 中做到这一点?
【问题讨论】:
【参考方案1】:简答
当 HTML 属性和 DOM 属性之间没有 1:1 映射时,必须使用 attribute binding syntax 否则 Angular 2 将报告“模板解析错误”。
例子:
[attr.my-custom-attribute]="myComponentValue"
[attr.colspan]="1 + 1"
在您的情况下,SVG 元素具有宽度和高度 DOM 属性,但它们不是您所期望的。它们是SVGAnimatedLength 对象。试图以旧方式设置它们的值不会做任何事情。这就是为什么您的模板不能按预期工作并且不报告错误的原因。切换到属性绑定语法将修复此行为:[attr.width]="width" [attr.height]="height"
深入讲解
属性绑定在 Angular 1 和 Angular 2 中的工作方式存在很大的概念差异。
在 Angular 1 中,设置自定义属性如下所示:
<div a-custom-attribute="I am a custom 'attribute' ">Text Content</div>
<div ng-attr-a-custom-attribute="I am a custom 'attribute' ">Text Content</div>
- this syntax 允许您绑定到原本会被浏览器急切处理的属性(例如 SVG 元素的 circle[cx] 属性、IMG 元素的 src 属性等)
在 Angular 2 中,情况有所不同:
Angular 2 引入了,正如他们所说的,a new mental model:不是绑定到 HTML 属性,而是绑定到 DOM 属性。了解 the distinction between an HTML attribute and a DOM property 对于了解 Angular 2 绑定的工作原理至关重要。
绑定到 DOM 属性可能如下所示:
<img [src]="heroImageUrl">
<img bind-src="heroImageUrl">
<img src=" heroImageUrl ">
- 这可能看起来有点混乱,特别是如果某人有 AngularJS 1 背景,但 Angular 2 在渲染视图之前将这些插值转换为相应的属性绑定 (source)。 重要的是要记住,正如Mark 在评论部分指出的那样,在对插值进行评估后,其结果随后会转换为字符串(@ 987654328@)。这意味着此语法仅限于分配字符串值。
请注意,如果名称无法匹配 DOM 属性,Angular 2 会报告“未知原生属性”错误:
// Template parse errors:
// Can't bind to 'colspan' since it isn't a known native property
<tr><td colspan="1 + 1">Three-Four</td></tr>
// Template parse errors:
// Can't bind to 'madeUpProperty' since it isn't a known native property
<div [madeUpProperty]="My custom 'madeUpProperty' "></div>
这意味着当没有要绑定的 DOM 属性时,必须使用attribute binding syntax。
最后,我相信作为一个好的经验法则,当他想要修改时,应该始终使用property binding's syntax(例如[src]="heroImageUrl"
)来支持插值(例如src="heroImageUrl"
)元素的 DOM 属性,因为后者仅限于传递字符串值。另一个原因是,如果某人有 AngularJS 1 背景,这应该可以减少设置属性和 DOM 属性之间的混淆。
【讨论】:
x="template_expression"
和[x]="template_expression"
之间存在细微差别——它们并不相同。使用
将template_expression
的结果转换为字符串,然后将其分配给属性x
。使用[]
,没有字符串转换步骤。因此,我不同意 Angular 文档中声明“没有技术理由偏爱一种形式而不是另一种形式”。如果我们想为属性x
分配字符串以外的东西,我们不能使用
,我们必须使用[]
。
@MarkRajcok 感谢您指出这一点。我已经编辑了我的答案。【参考方案2】:
<svg xmlns="http://www.w3.org/2000/svg/" [attr.width.px]="size" [attr.height.px]="size">
<rect [attr.width.px]="width" [attr.height.px]="height" fill="#DCB35C" />
</svg>
【讨论】:
.px
并不是真正需要的。这些是接受一个值的属性,然后它们在内部将 width
和 height
应用于 svg
和 rect
元素。看看this plunkr
我只是通知px
在绘图时不需要svg
developer.mozilla.org/en-US/docs/Web/SVG/Element/rect
同意。请注意,我没有说它是必需的,但也不能那样使用。【参考方案3】:
您应该使用属性绑定来绑定width
和height
,方法是在绑定之前添加attr
前缀,例如[attr.*]
。
标记
<svg xmlns="http://www.w3.org/2000/svg/" [attr.width]="size" [attr.height]="size">
<rect [attr.width]="width" [attr.height]="height" fill="#DCB35C" />
</svg>
类
import Component from 'angular2/core';
import bootstrap from 'angular2/platform/browser';
@Component(
selector: 'demo-app',
templateUrl: 'src/app.html',
pipes: []
)
export class App
width: number = 100;
height: number=100;
size: number=100;
constructor()
bootstrap(App);
Demo Plunkr
根据要求通过具有一些常量字符串值附加大小值,您只需将其放在attribute
上,如[attr.width]="size + '5'"
<svg xmlns="http://www.w3.org/2000/svg/" [attr.width]="size" [attr.height]="size">
<rect [attr.width]="width + '5'" [attr.height]="height + '5'" fill="#DCB35C" />
</svg>
Updated Plunkr
【讨论】:
thx,如果我想让 将 1 附加到 size 字符串怎么办? @lys1030 查看更新后的答案。它也有演示 plunkr。如果你想将宽度增加一倍,那么请执行[attr.width]="size+1"
我的意思不是“加 1”,而是“追加 1”。例如,如果 size = 10,我想附加一个 5,得到 105。
然后将其大小保持为字符串而不是数字
谢谢!你和 Cosmin 都给出了很好的答案。我在犹豫要接受哪一个。在我决定之前,我会等几天看看投票结果。以上是关于如何在 html 元素属性中使用 Angular 2 外推?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Angular Js 中使用名称或 id 属性验证表单
在 Angular 2 中,如何将数组字符串元素放入模板元素值属性中?
如何在Angular 2中使用ngStyle将transform translate属性应用于元素