在 ListView 项目模板中为按钮添加事件处理程序,传递附加参数
Adding event handler for button in the ListView item template, passing additional arguments
假设我有要在屏幕上显示的项目列表。每个项目都应显示为包含项目 ID、名称和值的行。此外,应该有一个按钮允许用户从列表中删除项目。
这是商品型号:
import observableModule = require("data/observable");
class ItemModel extends observableModule.Observable {
constructor(id: number, name: string, value: string) {
super();
this.set("id", id);
this.set("name", name);
this.set("value", value);
}
remove() {
console.log("inside remove method in item model");
}
}
export = ItemModel;
这是页面视图模型:
import observableModule = require("data/observable");
import observableArrayModule = require("data/observable-array");
import itemModel = require("./itemModel");
class BindingsTestViewModel extends observableModule.Observable {
items: observableArrayModule.ObservableArray<itemModel>;
constructor() {
super();
this.items = new observableArrayModule.ObservableArray<itemModel>();
this.items.push(new itemModel(100, "Item 1", "Value 1"));
this.items.push(new itemModel(101, "Item 2", "Value 2"));
this.items.push(new itemModel(102, "Item 3", "Value 3"));
this.items.push(new itemModel(103, "Item 4", "Value 4"));
}
remove() {
console.log("inside remove method in main VM");
}
}
export = BindingsTestViewModel;
最后,这是观点:
<Page loaded="load">
<StackLayout orientation="vertical">
<ListView items="{{ items }}">
<ListView.itemTemplate>
<GridLayout columns="50px,*,*,auto" cssClass="itemContainer" >
<Label col="0" text="{{ '#' + id }}" cssClass="itemId" />
<Label col="1" text="{{ name }}" cssClass="itemName"/>
<Label col="2" text="{{ value }}" />
<Button col="3" cssClass="deleteButton" text="Delete" tap="{{ remove }}">
</Button>
</GridLayout>
</ListView.itemTemplate>
</ListView>
</StackLayout>
</Page>
viewModel 在页面加载时被实例化并分配给 page.bindingContext。项目列表是可观察的数组,它绑定到 ListView 小部件。如您所见,项目模板中的按钮具有为点击事件定义的事件处理程序 - tap="{{ remove }}"
。
因此,当我单击 "Delete" 按钮时,remove() 方法在 页面视图模型(父级) 和 不是项目模型 。这是非常出乎意料的,因为文本绑定的相同句柄语法 - text={{ name }}
导致从当前项模型获取值。这意味着数据绑定声明和事件处理程序声明的上下文不同。
问题
- 是否可以将绑定到当前项的函数注册为事件处理程序?
- 是否可以将额外的参数传递给事件处理函数。例如。将项目的 ID 传递给 remove 函数,这样我就可以识别该项目并将其从列表中删除。我尝试了以下方法,但它们都不起作用:
tap="{{ remove(id) }}"
tap="{{ function() { remove(id); } }}"
tap="remove(id)"
tap="function() { remove(id); }"
事实上,您可以使用视图模型中的函数作为事件处理程序:
...tap="{{ remove }}"...
您可以像这样访问 UI 元素和 bindingContext:
function remove(args) {
var btn = args.object;
var item = btn.bindingContext;
}
假设我有要在屏幕上显示的项目列表。每个项目都应显示为包含项目 ID、名称和值的行。此外,应该有一个按钮允许用户从列表中删除项目。
这是商品型号:
import observableModule = require("data/observable");
class ItemModel extends observableModule.Observable {
constructor(id: number, name: string, value: string) {
super();
this.set("id", id);
this.set("name", name);
this.set("value", value);
}
remove() {
console.log("inside remove method in item model");
}
}
export = ItemModel;
这是页面视图模型:
import observableModule = require("data/observable");
import observableArrayModule = require("data/observable-array");
import itemModel = require("./itemModel");
class BindingsTestViewModel extends observableModule.Observable {
items: observableArrayModule.ObservableArray<itemModel>;
constructor() {
super();
this.items = new observableArrayModule.ObservableArray<itemModel>();
this.items.push(new itemModel(100, "Item 1", "Value 1"));
this.items.push(new itemModel(101, "Item 2", "Value 2"));
this.items.push(new itemModel(102, "Item 3", "Value 3"));
this.items.push(new itemModel(103, "Item 4", "Value 4"));
}
remove() {
console.log("inside remove method in main VM");
}
}
export = BindingsTestViewModel;
最后,这是观点:
<Page loaded="load">
<StackLayout orientation="vertical">
<ListView items="{{ items }}">
<ListView.itemTemplate>
<GridLayout columns="50px,*,*,auto" cssClass="itemContainer" >
<Label col="0" text="{{ '#' + id }}" cssClass="itemId" />
<Label col="1" text="{{ name }}" cssClass="itemName"/>
<Label col="2" text="{{ value }}" />
<Button col="3" cssClass="deleteButton" text="Delete" tap="{{ remove }}">
</Button>
</GridLayout>
</ListView.itemTemplate>
</ListView>
</StackLayout>
</Page>
viewModel 在页面加载时被实例化并分配给 page.bindingContext。项目列表是可观察的数组,它绑定到 ListView 小部件。如您所见,项目模板中的按钮具有为点击事件定义的事件处理程序 - tap="{{ remove }}"
。
因此,当我单击 "Delete" 按钮时,remove() 方法在 页面视图模型(父级) 和 不是项目模型 。这是非常出乎意料的,因为文本绑定的相同句柄语法 - text={{ name }}
导致从当前项模型获取值。这意味着数据绑定声明和事件处理程序声明的上下文不同。
问题
- 是否可以将绑定到当前项的函数注册为事件处理程序?
- 是否可以将额外的参数传递给事件处理函数。例如。将项目的 ID 传递给 remove 函数,这样我就可以识别该项目并将其从列表中删除。我尝试了以下方法,但它们都不起作用:
tap="{{ remove(id) }}"
tap="{{ function() { remove(id); } }}"
tap="remove(id)"
tap="function() { remove(id); }"
事实上,您可以使用视图模型中的函数作为事件处理程序:
...tap="{{ remove }}"...
您可以像这样访问 UI 元素和 bindingContext:
function remove(args) {
var btn = args.object;
var item = btn.bindingContext;
}