Реализация поведения переключателя с использованием переключателя в Nativescript (angular 2)

#angular #data-binding #nativescript #angular2-nativescript

#angular #привязка данных #nativescript #angular2-nativescript

Вопрос:

Я пытаюсь имитировать поведение переключателя в nativescript, но у меня возникают проблемы с привязкой. Приведенный ниже код почти работает, но если я «долго нажимаю» или как бы провожу пальцем по одному из переключателей, я не верю, что привязка работает, потому что тогда она не отменяется, когда я нажимаю другой переключатель.

 <StackLayout orientation="horizontal" *ngFor="let site of sites">
    <Label [text]="site.station_name" class="medium-spacing" (tap)="goToObserve()"></Label>
    <Switch text="" [checked]="isSiteSelected(site)" (tap)="toggleSite(site)"></Switch>
</StackLayout>
  

Вот функция компонента

 toggleSite(site) {
    setTimeout(() => {
        for(var s of this.sites) {
            if(s.station_id == site.station_id) {
                s.selected = true;
            }
            else {
                s.selected = false;
            }
        }
    }, 50);
}
  

Есть идеи по правильной реализации? Я пробовал различные итерации, используя [ngModel] и (PropertyChange)=»toggleSite(site)», но, похоже, ничего не работает. Также setTimeout кажется хакерским, но без него переключатель выглядел так, как будто он всегда был за переключателем.

Решение, которое я использую, основано на ответе @Nikolay Tsonev. Я рад, что смог избавиться от setTimeout . Вероятно, неверно, что я передаю оба параметра в toggleSite($event, site), но, похоже, это работает.

 <StackLayout orientation="vertical">
  <StackLayout orientation="vertical" class="data-grid">
    <StackLayout class="grid-header" orientation="horizontal">
      <Label text="Sites" class="left-column" width="70%"></Label>
      <Label text="Selected" class="right-column" width="30%"></Label>
    </StackLayout>
    <ScrollView height="50%">
      <StackLayout>
        <StackLayout orientation="horizontal" *ngFor="let site of sites" height="50">
          <Label text="{{ cameraIcon }}" (tap)="viewSitePhoto()" class="icon" width="10%"></Label>
          <Label [text]="site.station_name" class="medium-spacing" (tap)="viewSiteObservations()" width="60%" text-align="left"></Label>
          <Switch text="" [checked]="site.selected" (checkedChange)="toggleSite($event, site)" width="30%" text-align="right"></Switch>
            </StackLayout>
        </StackLayout>
    </ScrollView>
  </StackLayout>
</StackLayout>
  

и внутри моего компонента у меня есть:

 toggleSite(event, site) {
    let newSwitchValue = event.value;
    if(newSwitchValue) {
        for(var s of this.sites) {
            if(s.station_id == site.station_id) {
                s.selected = true;
            }
            else {
                s.selected = false;
            }
        }
    }
}
  

Ответ №1:

Вы могли бы использовать checkedChange событие переключения, которое уведомит вас, когда значение компонента было изменено. Я прилагаю пример кода. Для получения дополнительной помощи вы можете просмотреть эти примеры — примеры.

app.component.html

 <StackLayout orientation="horizontal" >
    <Label text="station_name" class="medium-spacing"></Label>
    <Switch  checked="isSiteSelected" (checkedChange)="selectedvalueChanged($event)"></Switch>
</StackLayout>
  

app.component.ts

 import {Component} from "@angular/core";

@Component({
    selector: "my-app",
    templateUrl: "app.component.html",
})
export class AppComponent {
    public counter: number = 16;

    public get message(): string {
        if (this.counter > 0) {
            return this.counter   " taps left";
        } else {
            return "Hoorraaay! nYou are ready to start building!";
        }
    }

    public onTap() {
        this.counter--;
    }
     public selectedvalueChanged(args) {
         console.log(args.object.checked)

}
}