简体   繁体   English

如何使用 ember-model 定义枚举

[英]How to define an enumeration with ember-model

In my ember-model model I need to set a String attribute from an enumeration.在我的 ember-model 模型中,我需要从枚举中设置一个 String 属性。 Is it possible with ember-model?用余烬模型可以吗?

By Example I would like to have a Book model:通过示例,我想要一个 Book 模型:

App.Book({
    id: Ember.attr(),
    title: Ember.attr( 'String' ),
    author: Ember.attr( 'String' ),
    status: App.BookStatus
});

and App.Book.Status as an enum with 3 possible values "FREE", "BORROW", "LOST" and use it:App.Book.Status作为具有 3 个可能值"FREE", "BORROW", "LOST"的枚举并使用它:

var myBook = App.Book.create({
    title:'myBook', 
    author:'fred', 
    status: App.BookStatus.FREE
})

I need the equivalent to the Java Enum feature我需要等效于 Java Enum 功能

public enum BookStatus {
    FREE, BORROW, LOST 
}

class Book {
    BookStatus bookStatus;
}

Book bookInstance = new Book();
bookInstance.bookStatus=BookStatus.LOST;

As stated in the docs:如文档中所述:

In Ember.js, an Enumerable is any object that contains a number of child objects, and which allows you to work with those children using the Ember.Enumerable API.在 Ember.js 中,Enumerable 是包含多个子对象的任何对象,它允许您使用 Ember.Enumerable API 处理这些子对象。

So for example:例如:

var players = ["Alex", "Paul", "Tom"];

players.forEach(function(item, index) {
  console.log('Player %@: %@'.fmt(index+1, item));
});

Would output:会输出:

// Player 1: Alex
// Player 2: Paul
// Player 3: Tom

To make your own custom class enumerable, you need two items:要使您自己的自定义类可枚举,您需要两个项目:

To make your own enumerable class/object in ember you could use the Ember.Enumerable mixin and follow this two requirements:要在 ember 中创建自己的可枚举类/对象,您可以使用Ember.Enumerable mixin 并遵循以下两个要求:

  • You must have a length property.你必须有一个length属性。 This property should change whenever the number of items in your enumerable object changes.只要可枚举对象中的项目数发生变化,此属性就会发生变化。 If you using this with an Ember.Object subclass, you should be sure to change the length property using the built-in set() method.如果您将它与Ember.Object子类一起使用,您应该确保使用内置的set()方法更改length属性。

  • If you must implement nextObject() .如果您必须实现nextObject()

Once you have these two methods implemented, apply the Ember.Enumerable mixin to your class and you will be able to enumerate the contents of your object like any other collection.实现这两个方法后,将Ember.Enumerable混入应用到您的类,您将能够像枚举任何其他集合一样枚举对象的内容。

Pseudo code:伪代码:

App.MyEnumObject = Ember.Object.extend(Ember.Enumerable, {
  length: 0,
  nextObject: function() {
    //return the next object of the enumeration
  }
  //more methods and properties
});

See here for more info on enumerable in ember.有关 ember 中可枚举的更多信息,请参见此处

Hope it helps.希望能帮助到你。

Edit编辑

Since we are using javascript, what you are trying to do could be done in a much simpler way.由于我们使用的是 javascript,因此您可以以更简单的方式完成您想要做的事情。 For example:例如:

App.bookStatus = {
  FREE: "FREE",
  BORROW: "BORROW",
  LOST: "LOST"
}
  
var myBook = App.Book.create({id: 1, title: 'myBook', author: 'fred', status: App.bookStatus.FREE})

For simple enum's in Ember, just using a simple JavaScript object, as shown at the bottom of @intuitivepixel's answer would suffice, but you can get a bit more functional, Ember-style enums with ember-computed-enum .对于 Ember 中的简单枚举,只需使用一个简单的 JavaScript 对象,如@intuitivepixel 答案的底部所示就足够了,但是您可以使用 ember-computed-enum获得更多功能的 Ember 风格的枚举

It allows getting and setting by more JavaScript-style-friendly names:它允许通过更 JavaScript 风格友好的名称获取和设置:

myBook.get('status');  // -> 'free'
myBook.set('status', 'lost');
myBook.get('status');  // -> 'lost'
myBook.save();  // -> saves `status: "LOST"` to the server

but also adds enumNameIsValue properties that are particularly useful in templates:还添加了在模板中特别有用的enumNameIsValue属性:

myBook.get('statusIsLost');  // -> true
myBook.get('statusIsFree');  // -> false

Install with ember install ember-computed-enum , then usage is pretty simpleember install ember-computed-enum ,然后使用就很简单了

Assuming your model looks something like:假设您的模型看起来像:

// app/models/book.js

import DS from 'ember-data';

export default DS.Model.extend({
  title: DS.attr('string'),
  author: DS.attr('string'),
  statusCode: DS.attr('string')
});

Where statusCode is returned from the server as one of "FREE" , "BORROW" , or "LOST"从服务器返回statusCode作为"FREE""BORROW""LOST"

You would add a mixin-style Ember enum like this:你可以像这样添加一个混合风格的 Ember 枚举

// app/models/book.js

import DS from 'ember-data';
import { computedEnumMixin } from 'ember-computed-enum';

BOOK_STATUS_ENUM = {
  free: "FREE",
  borrow: "BORROW",
  lost: "LOST"
};

export default DS.Model.extend(
  computedEnumMixin('status', 'statusCode', BOOK_STATUS_ENUM),
  {
  title: DS.attr('string'),
  author: DS.attr('string'),
  statusCode: DS.attr('string')
});

If you're not able to change the name of the status field to statusCode in the API, and still want to use the name status to access the value within your code, you can remap the model field name using a serializer :如果您无法在 API 中将status字段的名称更改为statusCode ,并且仍想使用名称status来访问代码中的值,则可以使用序列化程序重新映射模型字段名称

// app/serializers/book.js

import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({
  attrs: {
    statusCode: 'status'  // map the API's "status" field to the "statusCode" field on the model
  }
});

Note: I've made the examples to reflect current (Feb 2017) ember-cli conventions, rather than the older globals style of the question注意:我已经制作了示例以反映当前(2017 年 2 月)的 ember-cli 约定,而不是问题的较旧的全局样式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM