Aurelia ValueConverter fromView与多选混淆 [英] Aurelia ValueConverter fromView confusion with multi-select

查看:44
本文介绍了Aurelia ValueConverter fromView与多选混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在多选表单的上下文中使用和了解Aurelia ValueConverter.我认为直截了当的事实证明,这对我来说是一个挑战.

I'm trying to use and understand the Aurelia ValueConverter in the context of a multi-select form. What I thought would be straight forward, has turned out to be a challenge for me.

我有一个用于创建新交易的表单,该交易具有通过多选输入字段分配给它的多个类别.我已经将表单的输出绑定到new_deal.categorizations中(在数据库交易中,分类具有通过分类的类别).

I have a form to create a new deal which has multiple categories assigned to it via a multi-select input field. I've bound the output from the form into new_deal.categorizations (in the database deals have categories through categorizations).

现在,在创建时,我将通过蛮力"方法将每个类别ID转换为{category_id:id}对象,然后再发布到API.

Right now on create, through a 'brute force' method, I'm converting each category ID into a {category_id: id} object before posting to the API.

仅记录POST输出的示例:

Example just logging the POST output:

  create(){
      var categorizations = this.new_deal.categorizations;
      this.new_deal.categorizations = categorizations.map(function (e) {
          return {category_id: e}
      });
      logger.debug ('POST: ', JSON.stringify(this.new_deal));
  }

示例输出:

POST:  {"name":"new deal","categorizations":[{"category_id":"1"},{"category_id":"2"}]}

但是我认为最好通过ValueConverter实现.

But I think this would better be accomplished through a ValueConverter.

柱塞在此处包含完整代码,但基本上是:

Plunker is here with the full code but it's basically:

app.js:

export class App {
  constructor(){
    this.categories = [{id: 1, name: 'test1'}, {id: 2, name: 'test2'}];
    this.new_deal = {
        name:       'new deal',
        categorizations: null,
    };
  }

  create(){
      var categorizations = this.new_deal.categorizations;
      this.new_deal.categorizations = categorizations.map(function (e) {return {category_id: e}});
      logger.debug ('POST: ', JSON.stringify(this.new_deal));
  }

  create2(){
      logger.debug ('POST: ', JSON.stringify(this.new_deal));
  }

}

export class CategoryToIDValueConverter {
    fromView(id) {
        return id ? id: null;
    }
}

还有app.html:

And app.html:

<template>
  <h1>Testing ValueConverter</h1>
   <h3 >New Brute Force Deal</h3>
     <form role="form">
       <label>Name</label>
          <input type="text" placeholder="Ex. Buy One Get One Free" value.bind="new_deal.name">
       <label>Categories</label>
          <select value.bind="new_deal.categorizations" multiple size="2">
              <option repeat.for="category of categories" value.bind="category.id">${category.name}</option>
          </select>
       </form>
       <button type="submit" click.delegate="create()">Save</button>

  <h3>New ValueConverter Deal</h3>
    <form role="form">
      <label>Name</label>
          <input type="text" placeholder="Ex. Buy One Get One Free" value.bind="new_deal.name">
      <label>Categories</label>
          <select class="form-control" value.bind="new_deal.categorizations | categoryToID" multiple size="2">
            <option repeat.for="category of categories" value.bind="category.id">${category.name}</option>
          </select>
    </form>
    <button class="btn btn-success" type="submit" click.delegate="create2()">Save</button>
</template>

这样我得到

POST:  {"name":"new deal","categorizations":["1","2"]}

在app.js的fromView中,我认为我可以更改:

In fromView in app.js, I would think I could change:

return id ? id: null;

要返回一个对象而不是单个值:

To return an object instead of an individual value:

return id ? {category_id: id} : null

但这会导致此错误:

Uncaught Error: Only null or Array instances can be bound to a multi-select.

进一步检查后,似乎id以数组的形式进入了View.

Upon further inspection, it looks like id is coming into fromView as an array...

所以我将fromView修改为:

So I modified fromView to this:

    fromView(id) {
        if(id){
          var categorizations = [];
          id.forEach(function(cat_id){
            categorizations.push({category_id: cat_id})
          });
          logger.debug(categorizations);
          logger.debug(Object.prototype.toString.call(categorizations));
          return categorizations;
        } else { return null; }
    }
}

尝试期望一个数组,然后构建一个返回的分类对象数组,但是正如您在

Trying to expect an array, and then build an array of categorization objects to return, but as you can see in this Plunker, it loses the select as you click (though the debug logs show the objects being created).

推荐答案

您有一组类别对象,每个类别对象都有一个name(字符串)和id(数字).这些将用于填充允许多个选择的选择元素:

You have an array of category objects, each having a name (string) and id (number). These will be used to populate a select element that allows multiple selection:

export class App {
  categories = [
    { id: 1, name: 'test1'},
    { id: 2, name: 'test2'}
  ];
}

<select multiple size="2">
  <option repeat.for="category of categories">${category.name}</option>
</select>

交易对象由name(字符串)和categorizations组成.分类对象如下所示:{ category_id: 1 }

The deal object is comprised of a name (string) and categorizations. Categorization objects look like this: { category_id: 1 }

export class App {
  categories = [
    { id: 1, name: 'test1'},
    { id: 2, name: 'test2'}];

  deal = {
    name: 'new deal',
    categorizations: [],
  }
}

我们想将选择元素的值绑定到交易对象的分类(即对象数组).这意味着每个选择元素的选项都需要具有一个对象值". HTMLOptionElement的value属性仅接受字符串.我们分配给它的任何内容都将被强制为字符串.我们可以将分类对象存储在特殊的model属性中,该属性可以处理任何类型.有关更多信息,请参见 aurelia文档.

We want to bind the select element's value to the deal object's categorizations which is an array of objects. This means each of the select element's options need to have a object "value". An HTMLOptionElement's value attribute only accepts strings. Anything we assign to it will be coerced to a string. We can store the categorization object in a special model attribute which can handle any type. More info on this can be found in the aurelia docs.

<select multiple size="2">
  <option repeat.for="category of categories" model.bind="{ category_id: category.id }">${category.name}</option>
</select>

最后,我们需要将select元素的值绑定到交易对象的分类:

Finally we need to bind the select element's value to the deal object's categorizations:

<select value.bind="deal.categorizations" multiple size="2">
  <option repeat.for="category of categories" model.bind="{ category_id: category.id }">${category.name}</option>
</select>

所有视图和视图模型看起来像这样:

All together, the view and view-model look like this:

export class App {
  categories = [
    { id: 1, name: 'test1'},
    { id: 2, name: 'test2'}];

  deal = {
    name: 'new deal',
    categorizations: [],
  }

  createDeal() {
    alert(JSON.stringify(this.deal, null, 2));
  }
}

<template>
  <form submit.delegate="createDeal()">
    <label>Name</label>
    <input type="text" placeholder="Ex. Buy One Get One Free" value.bind="deal.name">

    <label>Categories</label>
    <select value.bind="deal.categorizations" multiple size="2">
      <option repeat.for="category of categories" model.bind="{ category_id: category.id }">${category.name}</option>
    </select>

    <button type="submit">Save</button>
  </form>
</template>

这是一个工作正常的人: http://plnkr.co/edit/KO3iFBostdThrHUA0QHY?p=preview

Here's a working plunker: http://plnkr.co/edit/KO3iFBostdThrHUA0QHY?p=preview

这篇关于Aurelia ValueConverter fromView与多选混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆