简体   繁体   English

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

[英]How to use Angular 2 extrapolation in html element attributes?

I want to bind some data to non-custom html element attributes. 我想将一些数据绑定到非自定义html元素属性。 However, the {{ }} in attributes is not extrapolated. 但是,属性中的{{}}不是外推的。 I've looked at other related posts as " Angularjs templateUrl fails to bind attributes inside ng-repeat ", which is a angular 1 solution for custom directives. 我已将其他相关帖子视为“ Angularjs templateUrl无法绑定ng-repeat内的属性 ”,这是自定义指令的角度1解决方案。

For example, I have: 例如,我有:

size = 500;

I want the following SVG element to work properly: 我希望以下SVG元素正常工作:

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

How should I do this in Angular 2? 我应该如何在Angular 2中做到这一点?

Short answer 简短的回答

When there isn't an 1:1 mapping between an HTML attribute and a DOM property one must use the attribute binding syntax otherwise Angular 2 will report a "template parse error". 当HTML属性和DOM属性之间没有1:1映射时,必须使用属性绑定语法,否则Angular 2将报告“模板解析错误”。

Examples: 例子:

  • [attr.my-custom-attribute]="myComponentValue"
  • [attr.colspan]="1 + 1"

In your case, an SVG element has the width and height DOM properties but they aren't what you expect. 在您的情况下,SVG元素具有宽度和高度DOM属性,但它们不是您所期望的。 They're SVGAnimatedLength objects. 它们是SVGAnimatedLength对象。 Trying to set their value the old way won't do anything. 试图以旧的方式设置他们的价值将不会做任何事情。 That's why your template doesn't work as you expect and doesn't report an error. 这就是为什么您的模板不能按预期工作并且不报告错误的原因。 Switching to attribute binding syntax would fix this behaviour: [attr.width]="width" [attr.height]="height" 切换到属性绑定语法将解决此问题: [attr.width]="width" [attr.height]="height"

In depth explanation 深入解释

There's a big conceptual difference between how attribute bindings work in Angular 1 and Angular 2. 在Angular 1和Angular 2中属性绑定的工作原理之间存在很大的概念差异。

In Angular 1, setting a custom attribute looks like this: 在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 allows you to bind to attributes that would otherwise be eagerly processed by browsers (eg an SVG element's circle[cx] attributes, the src attribute of a IMG element, etc) <div ng-attr-a-custom-attribute="I am a custom {{ 'attribute' }}">Text Content</div> - 此语法允许您绑定到浏览器急切处理的属性(例如,SVG元素的circle [cx]属性,IMG元素的src属性等)

In Angular 2, there's a different story: 在Angular 2中,有一个不同的故事:

Angular 2 introduced, as they put it, a new mental model : instead of binding to HTML attributes it binds to DOM properties . 正如他们所说,Angular 2引入了一个新的心理模型 :它不是绑定到HTML属性,而是绑定到DOM属性 Understanding the distinction between an HTML attribute and a DOM property is crucial to getting a grasp of how Angular 2 binding works. 理解HTML属性和DOM属性之间的区别对于掌握Angular 2绑定的工作原理至关重要。

Binding to a DOM property may looks like this: 绑定到DOM属性可能如下所示:

  • <img [src]="heroImageUrl">
  • <img bind-src="heroImageUrl">
  • <img src="{{ heroImageUrl }}"> - this may look a bit confusing, especially if someone has an AngularJS 1 background, but Angular 2 translates these interpolations into the corresponding property bindings before rendering the view ( source ). <img src="{{ heroImageUrl }}"> - 这可能看起来有点令人困惑,特别是如果某人有AngularJS 1背景,但Angular 2会在渲染视图( )之前将这些插值转换为相应的属性绑定。 It's important to have in mind that, as Mark pointed out in the comment section, after an interpolation has been evaluated, its result is then converted to a string ( source ). 重要的是要记住,正如Mark在评论部分中指出的那样,在评估插值之后, 其结果然后被转换为字符串 )。 This implies that this syntax is limited to only assigning string values. 这意味着此语法仅​​限于分配字符串值。

Note that if the name fails to match a DOM property, Angular 2 reports an "unknown native property" error: 请注意,如果名称与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>

This means that one must use the attribute binding syntax when there is no DOM property to bind to. 这意味着当没有要绑定的DOM属性时,必须使用属性绑定语法

Finally, I believe that as a good rule of thumb one should always use the property binding's syntax (eg [src]="heroImageUrl" ) in favor of interpolation (eg src="{{heroImageUrl}}" ) whenever he wants to modify the element's DOM property since the latter is limited to only passing string values. 最后,我认为作为一个好的经验法则,每当他想修改时,应该始终使用属性绑定的语法 (例如[src]="heroImageUrl" )支持插值(例如src="{{heroImageUrl}}" )元素的DOM属性,因为后者仅限于传递字符串值。 Another reason is that if someone has an AngularJS 1 background, this should reduce the confusion between setting an attribute and a DOM property. 另一个原因是,如果有人拥有AngularJS 1背景,这应该减少设置属性和DOM属性之间的混淆。

You should bind width & height using attribute binding by having attr prefix before binding like [attr.*] . 您应该使用属性绑定绑定widthheight方法是在绑定之前使用attr前缀,如[attr.*]

Markup 标记

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

Class

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 演示Plunkr


As requested appending value of size by having some constant string value, You just need to put that on attribute like [attr.width]="size + '5'" 通过具有一些常量字符串值来请求附加大小值,您只需将其放在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 更新了Plunkr

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM