Aurelia绑定 - 返回按钮点击查看模型

时间:2016-05-11 19:32:20

标签: javascript aurelia aurelia-binding

在Aurelia应用程序中,我有一个"重命名"单一输入的表单

<input ... value.bind="something.name" />

和两个按钮:SaveCancel

其他控件中已使用相同的something对象。因此,我不希望在name按钮被点击之前更改Save

是否有一个很好的声明方式来实现,或者我是否必须将name复制到另一个属性,然后将其复制回Save触发器?

4 个答案:

答案 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;绑定行为。绑定会做这些事情:

  1. 拦截updateSource以将写入重定向到隐藏存储空间
  2. 侦听保存事件,将隐藏的存储写回原始来源。
  3. &#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

    参考:内置throttle binding behavior

答案 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等