Докато надграждате върху angular, независимо дали е широкомащабно корпоративно приложение или просто малък страничен проект, определено ще се окажете в етап с изискване за двупосочно обвързване на данни. Обикновено за малки приложения можете да използвате променлива за данни в същия компонент, но с нарастването на кода и изискванията може да има сценарии, при които ще трябва да използвате една и съща или множество променливи в различни компоненти в рамките на проекта.
Когато става въпрос за обвързване, има предимно три различни метода, които Angular предлага.
- Свързване на свойства — -› []
- Обвързване на събитие — -› ()
- Двупосочно подвързване (комбинация от двете по-горе)— -› [()] — -› това се нарича още „Банан в кутията“
Нека се опитаме да ги разберем, като използваме пример, в който манипулираме променлива „accountBalance“. Ще използваме родителски и дъщерен компонент; от родителя можете да кредитирате сума с 10, а от детето можете да дебитирате същата.
Обвързване на свойства и обвързване на събития
Първо, нека дефинираме нашия родителски компонент.
// parent_component.component.ts @Component({ selector: 'parent_component', templateUrl: './parent_component.component.html', styleUrls: ['./parent_component.component.css'] }) export class ParentComponent implements OnInit { accountBalance : any; ngOnInit() { this.accountBalance = 500; } creditAccountBalance() { this.accountBalance += 10; } }
Тук accountBalance е променлива, декларирана вътре в родителския компонент, ние ще предадем тази променлива на дъщерния компонент в селекторите на компоненти.
// parent_component.component.html <span> Balance Amount : {{accountBalance}} </span> <button (click)=creditAccountBalance()> Add Amount </button> <child_component [accountBalance]="accountBalance"> </child_component>
Ако променлива на компонент е предадена като Html атрибут (като този на последния ред), това е известно като свързване на свойства.
За да имаме angular да извиква някакъв код, когато се извършва действие/събитие, ние използваме обвързване за промяна на събитието. Класически пример за обвързване на събитие е click/change, което използвахме и в горния пример.
Сега нека дефинираме нашия дъщерен компонент с функция за дебитиране на салдото по сметката с 10. Дъщерният компонент може да слуша променливата, обвързана със свойството, като използва `@Input() декоратора`.
// child_component.component.ts @Component({ selector: 'child_component', templateUrl: './child_component.component.html', styleUrls: ['./child_component.component.css'] }) export class ChildComponent implements OnInit { @Input('accountBalance') accountBalance: any; debitAccountBalance() { this.accountBalance -= 10; } } // child_component.component.html <button (click)=debitAccountBalance()> Debit Amount </button>
Тук сумата ще бъде намалена с 10, но тъй като обвързването на свойства осигурява само еднопосочно обвързване, т.е. промяната, направена от родителския контролер, ще бъде разпозната в дъщерния контролер, но не и обратното. По този начин дебитираната стойност „accountBalance“ няма да бъде отразена в родителския компонент.
Двупосочно обвързване
За да разрешим проблема, който беше разгледан по-горе, ще трябва да използваме метода Банан в кутията. Но преди това нека разберем как можете да напишете персонализирани функции за свързване на събития. Първо, ще трябва да променим малко родителския Html.
// parent_component.component.html <span> Balance Amount : {{accountBalance}} </span> <button (click)=creditAccountBalance()> Add Amount </button> <child_component [accountBalance]="accountBalance" (accountBalanceChange)="this.accountBalance= $event"> </child_component>
За да излъчим това събитие, ще трябва също да обвържем събитието вътре в дъщерния компонент, като използваме декоратора @OUTPUT
.
// child_component.component.ts @Component({ selector: 'child_component', templateUrl: './child_component.component.html', styleUrls: ['./child_component.component.css'] }) export class ChildComponent implements OnInit { @Input('accountBalance') accountBalance: any; @Output() accountBalanceChange = new EventEmitter(); debitAccountBalance() { this.accountBalance -= 10; this.accountBalanceChange.emit(this.accountBalance); } }
С тази сума, дебитирана от дъщерния компонент, ще бъде призната и в родителския компонент. По-добър начин да напишете същото обвързване, но да използвате BANANA IN THE BOX [🍌], би бил нещо подобно.
// parent_component.component.html <span> Balance Amount : {{accountBalance}} </span> <button (click)=creditAccountBalance()> Add Amount </button> <child_component [accountBalance]="accountBalance" [(accountBalance)]="accountBalance"> </child_component>
Синтаксисът [()]
е лесен за демонстриране, когато елементът има настройваемо свойство, наречено x
, и съответното събитие, наречено xChange
.
Bravvvoooooo... така постигате двупосочно свързване между компонентите. Освен това можете да добавите други дъщерни компоненти и промяната на стойността вътре в един ще бъде призната и сред другите дъщерни и родителски компоненти.
Надявам се, тази статия е била полезна!!