在 Nativescript 的 ViewModel 方法上绑定 itemTap
Binding itemTap on ViewModel method in Nativescript
我对 Nativescript 事件处理有点困惑。我正在使用明确区分代码隐藏和视图模型的打字稿,并且我正在尝试将 itemTap 属性 绑定到视图模型方法(就像 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>
代码隐藏:
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();
}
视图模型:
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;
}
}
onItemTapped
方法不会被触发。如果我将 onItemTapped
放在代码隐藏中:
export function onItemTapped(args): void {
let tappedView: any = args.view;
let tappedItem: any = tappedView.bindingContext;
}
.. 它按预期工作。在 viewModel 中使用事件处理程序有什么问题,为什么 "HelloWorld" 示例如此具有误导性?
问题是,在第一种情况下,您的 onItemTapped 来自您的视图模型。因此,您应该像引用视图模型属性 items 和 name 一样引用它,这意味着使用双大括号:
<ListView items="{{ items }}" itemTap="{{ onItemTapped }}">
现在,如果 onItemTapped 函数放在您的代码隐藏文件中,那么您可以直接在代码中引用它:
<ListView items="{{ items }}" itemTap="onItemTapped">
我对 Nativescript 事件处理有点困惑。我正在使用明确区分代码隐藏和视图模型的打字稿,并且我正在尝试将 itemTap 属性 绑定到视图模型方法(就像 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>
代码隐藏:
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();
}
视图模型:
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;
}
}
onItemTapped
方法不会被触发。如果我将 onItemTapped
放在代码隐藏中:
export function onItemTapped(args): void {
let tappedView: any = args.view;
let tappedItem: any = tappedView.bindingContext;
}
.. 它按预期工作。在 viewModel 中使用事件处理程序有什么问题,为什么 "HelloWorld" 示例如此具有误导性?
问题是,在第一种情况下,您的 onItemTapped 来自您的视图模型。因此,您应该像引用视图模型属性 items 和 name 一样引用它,这意味着使用双大括号:
<ListView items="{{ items }}" itemTap="{{ onItemTapped }}">
现在,如果 onItemTapped 函数放在您的代码隐藏文件中,那么您可以直接在代码中引用它:
<ListView items="{{ items }}" itemTap="onItemTapped">