如何在 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 中,设置自定义属性如下所示:

&lt;div a-custom-attribute="I am a custom 'attribute' "&gt;Text Content&lt;/div&gt; &lt;div ng-attr-a-custom-attribute="I am a custom 'attribute' "&gt;Text Content&lt;/div&gt; - 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 属性可能如下所示:

&lt;img [src]="heroImageUrl"&gt; &lt;img bind-src="heroImageUrl"&gt; &lt;img src=" heroImageUrl "&gt; - 这可能看起来有点混乱,特别是如果某人有 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 并不是真正需要的。这些是接受一个值的属性,然后它们在内部将 widthheight 应用于 svgrect 元素。看看this plunkr 我只是通知px 在绘图时不需要svg developer.mozilla.org/en-US/docs/Web/SVG/Element/rect 同意。请注意,我没有说它是必需的,但也不能那样使用。【参考方案3】:

您应该使用属性绑定来绑定widthheight,方法是在绑定之前添加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属性应用于元素

如何更改 Angular 指令上的变量?

如何使用 Jquery 更改 Angular-UI 元素属性

如何在 Angular 2.0 中使用 formControl 访问 Native HTML Input 元素