Binding itemTap on ViewModel method in Nativescript

六月ゝ 毕业季﹏ 提交于 2019-12-24 08:49:31

问题


I am a little bit confused with Nativescript event handling. I am using typescript with clear separation of code-behind and viewmodel, and I am trying to bind an itemTap property to a viewmodel method (just like in the example shown in https://github.com/NativeScript/template-hello-world-ts/blob/master/main-view-model.ts).

XML:

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" loaded="pageLoaded" class="page">
  <StackLayout>
    <ListView items="{{ items }}" itemTap="onItemTapped">
      <ListView.itemTemplate>
        <Label text="{{ Name }}"/>
      </ListView.itemTemplate>
    </ListView>
  </StackLayout>
</Page>

Code-behind:

import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { EditItemViewModel } from '../../ViewModels/EditItemViewModel';

export function navigatingTo(args: EventData) {
    let page = <Page>args.object;
    page.bindingContext = new EditItemViewModel();
}

ViewModel:

import { Observable } from 'data/observable';
import { ObjectRelationalMapper } from '../Common/Data'
import { WebServiceDataManager } from '../Common/Data'

import { Item } from '../Models/Item';

export class EditItemViewModel extends Observable {
  _wsDataManager: WebServiceDataManager;
  _orm: ObjectRelationalMapper;
  _items: Array<Item>;

  get items(): Array<Item> {
    return this._items;
  }

  set items(items: Array<Item>) {
    this._items = items;
  }

  constructor() {
    super();
    this._wsDataManager = new WebServiceDataManager();
    this._orm = new ObjectRelationalMapper();
    this.listAllItems();
  }

  private listAllItems(): void {
    this._orm.getAllObjects(Item, this, this.onItemsReceived)
  }

  public onItemsReceived(items: Array<Item>) {
    this._items = items;
    this.notify({ object: this, eventName: Observable.propertyChangeEvent, propertyName: 'items', value: this._items });
  }

  public onItemTapped(args): void {
    let tappedView: any = args.view;
    let tappedItem: Item = tappedView.bindingContext;
  }
}

The onItemTapped method doesn't get fired. If I put onItemTapped in code-behind:

export function onItemTapped(args): void {
    let tappedView: any = args.view;
    let tappedItem: any = tappedView.bindingContext;
}

.. it works as expected. What is wrong with using event handlers in the viewModel and why is the "HelloWorld" example so misleading?


回答1:


The thing is that in the first case your onItemTapped is coming from your view-model. So you should reference it just like you are referencing the view-model properties items and name, meaning by using double curly brackets:

<ListView items="{{ items }}" itemTap="{{ onItemTapped }}">

Now, if the onItemTapped function is placed in your code-behind file, then you can reference it directly as written in your code:

<ListView items="{{ items }}" itemTap="onItemTapped">


来源:https://stackoverflow.com/questions/41163750/binding-itemtap-on-viewmodel-method-in-nativescript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!