Когда использовать квадратные скобки [] в директивах @Входы и когда нет?
Я немного смущен.
См. эту простую директиву:
@Directive({
selector: '[myDirective]'
})
export class MyDirective {
private text: string;
private enabled: boolean;
@Input() myDirective:string;
@Input('myText')
set myText(val: string) {
this.text = val;
}
@Input('myEnabled')
set myEnabled(val: boolean) {
this.enabled = val;
}
ngOnInit() {
console.log("myDirective string: " + this.myDirective);
console.log("myText string: " + this.text);
console.log("myEnabled boolean: " + this.enabled);
}
}
если мой html будет выглядеть так:
<div [myDirective]="myDefaultText" [myEnabled]="true" [myText]="abc"></div>
Выход будет:
myDirective string: myDefaultText real value // good
myEnabled boolean: true // good
myText string: undefined // Why?
Если я УДАЛИТЬ [] из myText
:
<div [myDirective]="myDefaultText" [myEnabled]="true" myText="abc"></div>
Выход будет:
myDirective string: myDefaultText real value // good
myEnabled boolean: true // good
myText string: abc // GOOD
Я также могу удалить []
из myEnabled
, и он тоже будет работать.
Итак, вот моя путаница - когда мне нужно использовать квадратные скобки []
, а когда нет, в то время как я хочу, чтобы пользователь, который будет использовать myDirective
, никогда не будет задаваться вопросом, если или нет, я думаю, что квадратные скобки []
всегда должен быть там. Не так ли?
Ответы
Ответ 1
Когда вы используете []
для привязки к @Input()
, это в основном выражение шаблона.
Точно так же отображение {{abc}}
ничего не отобразит (если у вас на самом деле нет переменной с именем abc
).
Если у вас есть строка @Input()
, и вы хотите привязать ее к константной строке, вы можете связать ее следующим образом: [myText]=" 'some text' "
или, короче, как обычный атрибут HTML: myText="some text"
.
Причина [myEnabled]="true"
была связана с тем, что true
является допустимым выражением шаблона, которое, конечно, оценивается с помощью логического true
.
Ответ 2
В скобках указано Angular, чтобы оценить выражение шаблона. Если вы опускаете скобки, Angular обрабатывает строку как константу и инициализирует свойство target этой строкой. Он не оценивает строку!
Не делайте следующую ошибку:
<!-- ERROR: HeroDetailComponent.hero expects a
Hero object, not the string "currentHero" -->
<hero-detail hero="currentHero"></hero-detail>
check: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding
Ответ 3
привязка []
предназначена для объектов, без нее значение является строкой. Будьте осторожны с типами.
В коде
<div [myDirective]="myDefaultText" [myEnabled]="true" [myText]="abc"></div>
вы пытались связать объект, но объект недоступен, поэтому значение равно undefined
. С другой стороны, если вы удаляете привязку, тогда объект ушел, у вас есть только значение string
, назначенное этому свойству.
Ответ 4
Я думаю, я понимаю, откуда твое замешательство. Когда вы говорите [myText]="abc"
вы ожидаете, что myText
- это свойство, определенное в моем компоненте, значение которого я хочу инициализировать как abc
. Но это не правильно. Но сначала позвольте понять немного больше о HTML.
В HTML вы можете определить такой элемент.
<input type="text" value="Bob">
input - это элемент, attributes
которого являются тип и значение. Когда ваш браузер анализирует это, он создаст запись DOM (объект) для этого элемента. Запись DOM будет иметь некоторые properties
такие как align, baseURI, childNodes, children и т.д. Итак, что разница между атрибутами HTML и свойствами DOM См. Ссылку.
Причина, по которой вам нужно это знать, заключается в том, что в мире Angular единственная роль атрибутов состоит в инициализации элемента и состояния директивы. Когда вы пишете привязку данных, вы имеете дело исключительно со свойствами и событиями целевого объекта. HTML атрибуты эффективно исчезают.
Все это означает, что если вы напишите <img [src]="heroImageUrl">
это означает, что src
НЕ является атрибутом, но является property
определенным внутри DOM img. А правая часть heroImageUrl
является выражением шаблона.
Простое различие между [myText]="abc"
и myText="abc"
заключается в том, что в первом случае вы запрашиваете angular установить свойство PROPERTY myText, где в последнем случае вы создаете ATTRIBUTE с именем myText, и этот атрибут будет иметь свой собственный DOM имущество. Angular не имеет дело с атрибутами.
Итак, <div [myDirective]="myDefaultText" [myEnabled]="true" [myText]="abc"></div>
итог: в <div [myDirective]="myDefaultText" [myEnabled]="true" [myText]="abc"></div>
вы, по сути, говорите, что:
- примените директиву
myDirective
к моему элементу div. - привязать переменную
myEnabled
к выражению справа. Выражение говорит true
, поэтому значение myEnabled равно true. -
myText
переменную myText
с выражением справа. Выражение говорит abc
. Определен ли какой-либо abc? Нет, поэтому выражение оценивается как неопределенное.