如何在html元素属性中使用Angular 2外推?

时间:2016-03-19 08:06:12

标签: javascript angularjs angular

我想将一些数据绑定到非自定义html元素属性。但是,属性中的{{}}不是外推的。 我已将其他相关帖子视为" Angularjs templateUrl fails to bind attributes inside ng-repeat",这是自定义指令的角度1解决方案。

例如,我有:

size = 500;

我希望以下SVG元素正常工作:

<svg xmlns="http://www.w3.org/2000/svg/" width="{{size}}" height="{{size}}">
<rect width="{{size}}" height="{{size}}" fill="#DCB35C"/>
</svg>

我应该如何在Angular 2中做到这一点?

3 个答案:

答案 0 :(得分:12)

简短回答

当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属性等)< / LI>

在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,在评估插值后,然后将其结果转换为字符串source)。这意味着此语法仅​​限于分配字符串值。

请注意,如果名称与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属性之间的混淆。

答案 1 :(得分:4)

你应该绑定width&amp; 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

答案 2 :(得分:4)

<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>