在Aurelia应用程序中,我有一个"重命名"单一输入的表单
<input ... value.bind="something.name" />
和两个按钮:Save
和Cancel
。
其他控件中已使用相同的something
对象。因此,我不希望在name
按钮被点击之前更改Save
。
是否有一个很好的声明方式来实现,或者我是否必须将name
复制到另一个属性,然后将其复制回Save
触发器?
答案 0 :(得分:2)
您可以为编辑弹出窗口创建模型对象,仅在单击Save
时复制对列表中项目所做的编辑。这是一个简单的例子:https://gist.run/?id=af3af031c5acc4c46407679f5ab1376b
查看
<template>
<ul>
<li repeat.for="person of people">${person.firstName} ${person.lastName} <button click.delegate="editPerson(person)">Edit</button></li>
</ul>
<div if.bind="editing">
First Name: <input type="name" value.bind="editModel.firstName" />
Last Name: <input type="name" value.bind="editModel.lastName" />
<button click.delegate="savePerson()">Save</button>
<button click.delegate="cancelEdit()">Cancel</button>
</div>
</template>
视图模型
export class App {
editing = false;
people = [
{ firstName: 'John', lastName: 'Doe' },
{ firstName: 'Jane', lastName: 'Smith' },
{ firstName: 'Bob', lastName: 'Smith' }
];
editPerson(person) {
this.editing = true;
this.editObject = person;
this.editModel = Object.assign({},person);
}
savePerson() {
this.editing = false;
Object.assign(this.editObject, this.editModel);
this.editObject = null;
this.editModel = null;
}
cancelEdit() {
this.personBeingEdited = null;
this.editing = false;
}
}
答案 1 :(得分:2)
我认为Ashley Grant的回答是一种非常明确/直接的做法。我会选择那样的东西。既然你要求使用更少代码的替代方法,那么你就去....不确定它是否更好,它只是另一种方式,可能不太清楚... < / p>
https://gist.run?id=e931202307361d472c3e0ee4f523a833
视图模型有一个名为editPerson
的属性,表示当前正在编辑的人。
<强> app.js 强>
export class App {
people = [
{ firstName: 'John', lastName: 'Doe' },
{ firstName: 'Jane', lastName: 'Smith' },
{ firstName: 'Bob', lastName: 'Smith' }
];
editPerson = null;
save() {
this.editPerson.firstName = this.firstNameInput.value;
this.editPerson.lastName = this.lastNameInput.value;
this.editPerson = null;
}
}
视图使用one-way
绑定将视图模型数据推送到输入中。对输入的编辑不会更新模型,因为绑定是一种方式。提交表单时,将调用视图模型的save()
方法,该方法具有将输入值复制到模型中的逻辑。
<强> app.html 强>
<template>
<ul>
<li repeat.for="person of people">
${person.firstName} ${person.lastName}
<button click.delegate="editPerson = person">Edit</button>
</li>
</ul>
<form if.bind="editPerson" submit.delegate="save()">
<label>
First Name:
<input ref="firstNameInput" value.one-way="editPerson.firstName">
</label>
<label>
Last Name:
<input ref="lastNameInput" value.one-way="editPerson.lastName">
</label>
<button type="submit">Save</button>
<button type="button" click.delegate="editPerson = null">Cancel</button>
</form>
</template>
答案 2 :(得分:2)
这是另一种使用自定义&#34;可取消&#34;绑定行为。绑定会做这些事情:
updateSource
以将写入重定向到隐藏存储空间&#34; 2&#34;通过约定来完成,该约定在绑定上下文中观察saved
属性。如果需要更大的灵活性,可以将属性名称作为参数传递给自定义绑定。
<强> app.html 强>
<template>
<require from='./cancellable'></require>
<div>
Name: ${name}
Age: ${age}
<button click.delegate="edit()">Edit</button>
</div>
<div if.bind="editing">
<h3>Cancellable edit</h3>
Name: <input value.bind="name & cancellable">
Age: <input value.bind="age & cancellable">
<div><button click.delegate="save()">Save</button>
<button click.delegate="cancel()">Cancel</button></div>
</div>
<div if.bind="editing">
<h3>Instant edit</h3>
Name: <input value.bind="name">
Age: <input value.bind="age">
</div>
</template>
<强> app.js 强>
export class App {
constructor() {
this.name = 'John';
this.age = 20;
this.editing = false;
this.saved = false;
}
edit() {
this.saved = false;
this.editing = true;
}
save() {
this.saved = true;
this.editing = false;
}
cancel() {
this.saved = false;
this.editing = false;
}
}
<强> cancellable.js 强>
import {inject} from 'aurelia-dependency-injection';
import {BindingEngine} from 'aurelia-binding';
@inject(BindingEngine)
export class CancellableBindingBehavior {
constructor(bindingEngine) {
this.bindingEngine = bindingEngine;
}
bind(binding, scope) {
let value;
let modified = false;
let cancellable = {
originalUpdateSource: binding.updateSource,
originalUpdateTarget: binding.updateTarget,
};
// 1. Intercept "updateSource" to redirect write to a hidden value storage
binding.updateSource = (val) => {
value = val;
modified = true;
};
// 2. Intercept updateTarget" so that can observe change from original source
binding.updateTarget = (val) => {
value = val;
modified = false;
cancellable.originalUpdateTarget.call(binding, val);
}
// 3. Observe the "saved" event to copy back to original source
let bindingContext = scope.bindingContext;
cancellable.subscription = this.bindingEngine.propertyObserver(bindingContext, 'saved')
.subscribe((newValue, oldValue) => {
if (newValue && modified) {
cancellable.originalUpdateSource.call(binding, value);
}
});
binding.cancellable = cancellable;
}
unbind(binding, scope) {
binding.updateSource = binding.cancellable.originalUpdateSource;
binding.updateTarget = binding.cancellable.originalUpdateTarget;
binding.cancellable.subscription.dispose();
binding.cancellable = null;
}
}
Gist run:https://gist.run/?id=2c7e40e88d1d3c18e9d2bca6be438b47
答案 3 :(得分:0)
我所做的是制作了我要编辑的对象的副本,然后将其绑定到视图,当我点击保存时,然后“合并”&#39;使用我的originalObject编辑的对象,以便更改反映在其他控件中。
所以我的编辑ViewModel看起来像这样:
activate(existingUser: User) {
let userCopy: User = JSON.parse(JSON.stringify(existingUser));
}
在我看来,我然后使用userCopy
对象来绑定属性。当我点击保存时,我会执行以下操作:
let indexOfUser = this.users.indexOf(existingUser);
Object.assign(this.users[indexOfUser], userCopy);
我已经简化了一些代码,因为在我的用例中我使用的对话框将editedUser返回到另一个ViewModel,并且是保存用户列表的ViewModel等