当前位置: 首页 > 软件库 > 程序开发 > >

emberx-select

授权协议 MIT License
开发语言 JavaScript
所属分类 程序开发
软件类型 开源软件
地区 不详
投 递 者 夏英发
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

emberx-select

A select component based on the native html select.

We've tried other select components, and were missing the reliability,maintainability, and accessbility of the native html <select>.<XSelect> is a drop-in component to let you use anyobject for your selectable options. You can use it out of the box, oras a building block of something more ambitious.

The goal of <XSelect> is to let you see how it works and style itright in your template, rather than passing in a ball of configurationor wrapping a hard-coded, inaccessible jQuery plugin.

Installation

ember install emberx-select

Usage

By allowing arbitrary html to appear in the template of the selectelement, you can use it just like you would normally. This meansthings like having <optgroup> tags inside your select, or even plainold <option> elements to represent things like empty values.

<XSelect> thinly wraps a native <select> element so that it can be objectand binding aware. It is used in conjuction with the x-optioncomponent to construct select boxes. E.g.

Ember >= 3.4:

<XSelect @value={{bob}} @onChange={{action "selectPerson"}} as |xs|>
  <xs.option @value={{fred}}>Fred Flintstone</xs.option>
  <xs.option @value={{bob}}>Bob Newhart</xs.option>
</XSelect>

Ember < 3.4:

{{#x-select value=bob on-change=(action "selectPerson") as |xs|}}
  {{#xs.option value=fred}}Fred Flintstone{{/xs.option}}
  {{#xs.option value=bob}}Bob Newhart{{/xs.option}}
{{/x-select}}

The options are always up to date, so that when the object bound tovalue changes, the corresponding option becomes selected.

Whenever the select tag receives a change event, it will fireonChange action. This is the default action that is fired but notthe only event that's available.

Contextual Components

As of version 3.0.0, emberx-select will only support contextualcomponents. This means you will have to use Ember 2.3 or higher. Usingcontextual components allows emberx-select to skip somepotentially expensive DOM traversals. Now the options can registerthrough data rather than through the DOM.

<XSelect @value={{model.status}} as |xs|>
  <xs.option @value=1>Active</xs.option>
  <xs.option @value=2>Inactive</xs.option>
</XSelect>

Multiselect

<XSelect> supports the multiple option. This means you can pass anarray as its value, and it will set its selections directly on thatarray.

<XSelect @value=selections @multiple=true @onChange={{action "selectionsChanged"}} as |xs|>
 <xs.option @value={{fred}}>Fred Flintstone</xs.option>
 <xs.option @value={{bob}}>Bob Newhart</xs.option>
 <xs.option @value={{andrew}}>Andrew WK</xs.option>
</XSelect>

The selections array will be initialized to an empty array if not present.

Actions and Action Arguments

All of <XSelect>s actions are closure actions. This means you must usethe action helper (i.e. @onClick={{action "onClick"}}). The functionthat is dispatched by <XSelect> whenever the event fires has a functionsignature of:

/**
* @param {Object} value - the value selected by the user.
* @param {Object} event - the DOM event of the action
*/
function (value, event) {
  // action body...
}

Most of the time all you need is the value that has been selected, butsometimes your action requires more context than just that. In thosecases, you can pass any arguments you need from the template. Forexample:

<XSelect @onClick={{action "didMakeSelection" isXSelectRequired}} @required={{isXSelectRequired}} as |xs|>
  <option>Nothing</option>
  <xs.option @value={{something}}>Something</xs.option>
</XSelect>

then, inside your action handler:

import Controller from '@ember/controller';

export default Controller.extend({
  actions: {
    didMakeSelection(value, event, isXSelectRequired) {
      if (!value & isXSelectRequired) {
        this.set('error', 'You must fill out this field');
      } else {
        this.set('selection', value);
      }
    }
  }
});

<XSelect> provides other actions that fire on different eventtypes. These actions follow the HTML input event naming convention.

onBlur

onBlur fires anytime the blur event is triggered on the <XSelect>component. When the action fires it sends two arguments: the value,the DOM event.

onFocusOut

onFocusOut fires anytime the focusOut event is triggered on the <XSelect>component. When the action fires it sends two arguments: the value,the DOM event.

onClick

onClick fires when <XSelect> is clicked. When the action fires itsends two arguments: the value, the DOM event.

onDisable (x-option)

onDisable fires when x-option detects a change to its disabledattribute. When the action fires it sends two arguments: the valueand if it is disabled (boolean).

Test Helper

<XSelect> 4.0 ships with an entirely new test helper that goesbeyond just allowing you to select an option. It allows you tointeract with your <select> element in all different ways. Forexample, if you need to assert your first option is disabledor not:

expect(xselect.options(0).isDisabled).to.equal(true);

Under the hood this new test helper is using a BigTestInteractor. Interactorsallow you to think about how you're going to interact with the DOMand abstract that into composable & immutable containers. Interactorsare similar to page objects, but for components.

Using the test helper

Import the select interactor:

// you can name the import whatever you want
import XSelectInteractor from 'emberx-select/test-support/interactor';

At the top of your test file you need to initialize theinteractor. This should go at the top most part of your test so it'savailable to all tests in the file. Here's an example in Qunit:

module("Acceptance | Your Test", function(hooks) {
  let xselect = new XSelectInteractor('.selector-for-select');
  setupApplicationTest(hooks);
  // ...
});

Once you have initialized the interactor, you're ready to startselecting!

module("Acceptance | Your Test", function(hooks) {
  let xselect = new XSelectInteractor('.selector-for-select');
  // ...

  test('Selecting an option', async (assert) => {
    await xselect
      .select('Fred Flintstone')
      .when(() => assert.equal(xselect.options(0).isSelected, true));

    // for a multiselect pass an array
    // await xselect
    //   .select(['Fred Flintstone', 'Bob Newhart'])
    //   .when(() => assert.equal(xselect.options(0).isSelected, true));;
  });
});

You can do more than just select options with this helper.

module('Acceptance | Your Test', function(hooks) {
  let xselect = new XSelectInteractor('.selector-for-select');
  // ...

  test('Selecting an option', async (assert) => {
    await xselect.select('Fred Flintstone')
      // assert the change is has happened. It's important to make the
      // assertion inside of `when`, so tests are not flakey.
      .when(() => assert.equal(xselect.options(0).isSelected, true));
  });
});

In this example we're using @bigtest/convergence#when toassert. The TL;DR of convergence is it basically converges on thestate of the DOM. It checks every 10ms until the assertion istruthy. Once it's truthy the test passes. You can read more aboutconvergences here

You don't need to include @bigtest/convergence in your project, it'salready a dependency of @bigtest/interactor and interactor providesall of the convergence methods to you (like when and do).

This is the full interactor which has all of the attributes orinteractions for an HTMLSelectElement.

const xSelectInteractor = interactor({
  hasFocus: is(':focus'),
  name: attribute('name'),
  form: attribute('form'),
  title: attribute('title'),
  size: attribute('size'),
  tabindex: attribute('tabindex'),
  isDisabled: property('disabled'),
  isRequired: property('required'),
  isAutofocus: property('autofocus'),

  options: collection('option', {
    name: attribute('name'),
    value: property('value'),
    title: attribute('title'),
    isSelected: property('selected'),
    isDisabled: property('disabled'),
    hasSelectedClass: hasClass('is-selected')
  })
});

Example usage might be:

<select name="World" class="x-select">
  <option value="hello world">Hello world!</option>
</select>
let xselect = new XSelectInteractor('.x-select');

xselect.options(0).value; //=> "hello world"
xselect.options(0).text; //=> "Hello World!"
xselect.name; //=> "World"
xselect.form; //=> null
xselect.hasFocus; //=> false
xselect.tabIndex; //=> 0

If you want to see this test helper used in many different ways lookno further than this addons test suite!

Extending the XSelect interactor

If you want to add custom interactions to your <XSelect> interactor,you can do so by importing it into the custom interactor you want tocreate, and extend it:

import XSelectInteractor from 'emberx-select/test-support/interactor';
import { clickable } from '@bigtest/interactor';

@XSelectInteractor.extend
class NewInteractor {
  submitForm = clickable('[data-test-form-submit]');

  fillAndSubmit(value) {
    return this.select(value).submitForm();
  }
}

EmberX

emberx-select is part of the "missing components of ember" collectivelyknown as emberx:

Other Resources

Running Tests

  • ember test
  • ember test --server

Release Process

Every commit to master results in a build and push to the demoapplication at http://emberx-select.netlify.com

Npm releases use semver and happen at the project owner's discretion.

Code of Conduct

Please note that this project is released with a Contributor Code ofConduct. By participating in this project you agree to abide by itsterms, which can be found in the CODE_OF_CONDUCT.md file in thisrepository.

  • 没错,x-select又出问题了。不得不说ember在版本之间的兼容真的差…… 问题是这样,用x-select写了个选择框,代码是这样的: {{#x-select value=model.sighting.cryptid class="form-control" as |xs|}} {{#xs.option disabled=true}}Select Cryptid{{/xs.option

  • 说起来也挺奇怪的,按照书上的写法再次报错,这书就不能靠谱一点…… 书上的例子就不放了,直接上解决方案吧。我在x-select的issue里发现了这么一条: Hey @newton3, if you’re using x-select 3.0 you should be using contextual components. If you update your HBS to this does

 相关资料
  • 问题内容: 我使用iBatis作为Java中的ORM框架。我有一条选择声明 我正在使用queryForList方法: 但是它会检索大量数据,并且此查询的性能非常慢。 我对此问题的假设是iBatis具有默认的提取大小(例如,在JDBS中为10),这就是为什么它这么慢的原因。所以我想设置更大的获取大小(例如1000)。我该怎么做? 还是我看错了方向? 注意:我需要所有数据,因此在method中设置ma

  • 问题内容: 我有一个安装了ACR122驱动程序的ACR122U NFC读写器连接到Windows计算机。 我尝试使用API将SELECT(通过AID)ADPU发送到我的Android设备(应该处于HCE模式)。 这是我的代码: 这是我得到的输出: 我想这是我的Android设备提供给NFC阅读器的UID。SELECT APDU不返回任何响应,它的长度为0个字节。 在我的Android设备上,我有以

  • 问题内容: 我创建了一个微调器,当有人使用阵列适配器添加设备时,该微调器会自动更新设备名称。我使用微调器创建了OnItemSelected方法,因此,当选择微调器中的名称之一时,将出现一个新窗口。但是,在活动开始时,OnItemSelected会自动选择列表中的第一个项目,因此,在新窗口出现之前,用户没有机会进行实际选择。 这是代码: 有谁知道不会自动选择列表中第一项的方法? 这是其余微调器的代码

  • 问题内容: 我有一个争论,我这样说道: 但它似乎不起作用。 我是sqlite的新手,请告诉我如何解决它。谢谢 ! 问题答案: 将通配符应用于参数,而不是SQL: 在SQL参数插值增加了报价给你,所以你的查询结束的,这不是有效的SQL。

  • 问题内容: 我从a取值并将其设置为内部条件 如 但这是行不通的。有什么建议? 问题答案: 尝试修剪字符串以确保没有多余的空格: 也可以使用@thinksteep之类的方法。

  • 问题内容: 我将如何在没有硬编码值的情况下编写此sql语句? 宁愿有这样的事情: 提前致谢.. 问题答案: 用您当前的方式构造SQL查询是一个糟糕的主意,因为它为各种SQL注入攻击打开了大门 。为了正确执行此操作,您必须改为使用“ 预备语句”。这也将解决您目前显然遇到的各种逃避问题。 请注意,这是一个昂贵的调用(除非您的应用程序服务器使用语句缓存和其他类似的功能)。从理论上讲,最好先准备一次语句,