Nativescript Observable Что-то не правильно - PullRequest
0 голосов
/ 23 ноября 2018

Потратил несколько часов только на то, чтобы заставить этот простой кусок работать.Сложные массивы работают нормально, но не понимаю, почему этот простой код не отображает данные.Использование nativescript 5.0

.ts file

public _contact: ObservableArray<string>;

    ngOnInit(): void {         

    }

    public pickContact()
    {
        Permissions.requestPermissions([android.Manifest.permission.GET_ACCOUNTS, android.Manifest.permission.WRITE_CONTACTS, android.Manifest.permission.READ_PHONE_STATE], "Access to google account required!")
        .then(() => {
            contacts.getContact().then(function(args){
                if (args.response === "selected") {
                    console.log("arg response selected .... ");
                    var _contact = args.data;
                    var name_given = _contact.name.given == null ? "" : _contact.name.given;
                    var name_middle = _contact.name.middle == null ? "" : _contact.name.middle;
                    var name_family = _contact.name.family == null ? "" : _contact.name.family;
                    var _contactName= name_given + " " + name_middle + " " + name_family;    
                    var _contactPhone = _contact.phoneNumbers[0].value;
                    alert("Data = " + _contactName + " " + _contactPhone);
                    this._contact = new ObservableArray([
                        {name:_contactName, phone:_contactPhone}
                    ]);  

                }
            })                
        });
    }

.html file

<StackLayout>
    <Button width="100" height="100" row="0" col="0" text="Refresh Calls" (tap)="pickContact()" horizontalAlignment="left" class="btn btn-rounded-sm m-20" style="background-color: rgb(60, 72, 179);color:white;font-weight:bold;"></Button>        
    <ListView [items]="_contact" height  = "270" class="list-group">            
            <ng-template let-result="item">
                <GridLayout rows="*,*" cols="" horizontalAlignment="left" verticalAlignment="top">
                    <Label row="0" col="0" [text]="result.name" class="h2 list-group-item lblThin" style="font-size:22;" (tap)="dialNumber(result.mobile)"></Label>
                    <Label row="1" col="0" [text]="result.phone" class="h4 list-group-item lblThin" (tap)="dialNumber(result.mobile)"></Label>                                                               
                </GridLayout>
            </ng-template>
        </ListView>
</StackLayout>

Высота в Listview равна 270 (фиксированное значение), так как я ожидаю, что только одна запись будетв этом ListView.При выборе контакта будет выбран только один контакт, а его имя и номер будут отображены в списке.Оповещение показывает правильные данные, но не отображает данные в html.

В дополнение к вышеупомянутой проблеме рендеринга, я хочу знать, есть ли способ избежать нажатия кнопки для вызова функции pickNumber.Я попытался перейти к ngOnInit и заметил, что они не выполняются.

1 Ответ

0 голосов
/ 23 ноября 2018

В этом коде есть несколько ошибок, которые могут быть неправильными.

public _contact: ObservableArray<string>;

this._contact = new ObservableArray([
    {name:_contactName, phone:_contactPhone}
]);
/* { name: string, phone: string } is not of type 'string' */

Кроме того, обратным вызовам API, которые обновляют элементы пользовательского интерфейса, обычно нравится, когда NgZone работает внутри.

Затем, чтобы сделать дела немного более грязными, вы используете отключенный function, который технически не должен ссылаться ни на одного из ваших this членов.

Попробуйте это:

class Contact: {
  constructor(public name: string, public phone: string) { }
}

@Component({ ... })
export class YourComponent {
  public contact$: Subject<Contact | null>;
  constructor(private zone: NgZone, ...) {
    this.contact$ = new BehaviourSubject<Contact | null>(null);
  }

  public pickContact() {
    Permissions. ...
      .then(() => {
        contacts.getContact().then((args) => {
          ...
          this.zone.run(() => {
            this.contact$.next(new Contact(contactName, contactPhone));
          }
        });
      });
  }
}

Чтобы улучшить это, вы, вероятно, захотите использовать несколько WeakRef, чтобы убедиться, что вы не удерживаете ссылки на объекты бесконечно (вызывая утечки памяти) во время ожидания вызовов API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...