Ember.Object实例中必需的属性(构造函数args) [英] Required properties (constructor args) in Ember.Object instances

查看:124
本文介绍了Ember.Object实例中必需的属性(构造函数args)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Ember中,假设我有一个名为 FoodStuff 的对象,其中有一些属性:

In Ember, let's say I have an object called FoodStuff that has a few properties:

export default Ember.Object.extend({
    name: null,     // REQUIRED: 'Slice of Apple Pie'
    calories: null, // OPTIONAL: int: eg. 250
    category: null, // REQUIRED: 'Pastry'
    rating: null    // OPTIONAL: int: 1-5
});

如何在Ember中编写一个构造函数,要求name和category属性在实例化时提供?

How can I write a 'constructor' in Ember, requiring that the 'name' and 'category' properties be provided at instantiation-time?

Angular似乎以相当简单的语法来处理:

Angular seems to approach this with fairly straightforward syntax:

.factory('User', function (Organisation) {

  /**
   * Constructor, with class name
   */
  function User(firstName, lastName, role, organisation) {
    // Public properties, assigned to the instance ('this')
    this.firstName = firstName;
    ...

使用JavaScript类的角度模型对象

Ember是否有类似的东西?目前我所有的类都在顶部,一些初始为空的属性可以由呼叫者正确设置可能或不可能。在构建时(我正在使用 ember-cli )我希望构造函数要求的更改被 ember build 与JSHint相位。

Does Ember have something similar? Currently all my classes are as seen at the top, with a bunch of initially null properties that might or might not be properly set by the caller. At build time (I'm using ember-cli) I would like for changes in constructor requirements to be caught downstream by the ember build phase with JSHint.

推荐答案

据我所知,在Ember中没有本机的方法。但没有什么不可能的!您可以调整Ember来处理这种情况。只需添加一个初始化程序:

As far as I know, there is no native way to do this in Ember. But there's nothing impossible! You can tweak Ember a bit to handle the case. Just add an initializer:

/initializers/extend-ember.js

import Ember from 'ember';

export function initialize() {

  Ember.Object.reopen({

    /**
     * @prop {Array} - array of required properties
     */
    requiredAttrs: [],

    /**
     * Validates existance of required properties
     *
     * @param {String} attr - attribute name
     * @param {*} value - value of the property
     * @throws {Error} in case when required property is not set
     */
    _validateExistance(attr, value) {
      if (this.requiredAttrs.contains(attr) && typeof value === "undefined") {
        throw new Error("Attribute " + attr + " can't be empty!");
      }
    },

    /**
     * Sets value of a property and validates existance of required properties
     *
     * @override 
     */
    set(key, value) {
      this._validateExistance(key, value);
      return this._super(key, value);
    }

  });

  Ember.Object.reopenClass({

    /**
     * Creates object instance and validates existance of required properties
     *
     * @override
     */
    create(attrs) {
      let obj = this._super(attrs);
      if (attrs) {
        obj.requiredAttrs.forEach((key) => {
          obj._validateExistance(key, attrs[key]);
        });
      }
      return obj;
    }

  });

}

export default {
  name: 'extend-ember',
  initialize: initialize
};

然后你可以使用 requiredAttrs 类定义需要哪些属性。如果您尝试使用空的必需属性创建一个实例,或尝试将空值设置为必需属性,它将抛出异常。

Then you can use requiredAttrs property on any class to define which properties are required. It will throw an exception if you try to create an instance with empty required properties or if you try to set an empty value to required property.

let MyModel = Ember.Object.extend({
  prop1: null,
  prop2: null,
  requiredAttrs: ['prop2']
});

let ChildModel = MyModel.extend({
  prop3: null,
  requiredAttrs: ['prop2', 'prop3']
});

// throws exception
let obj1 = MyModel.create({
  prop1: 'val1'
});

// no exception
let obj2 = MyModel.create({
  prop2: 'val2'
});

// throws exception
obj2.set('prop2', undefined);

// throws exception
let obj3 = ChildModel.create({
  prop3: 'val3'
});

// no exception
let obj4 = ChildModel.create({
  prop2: 'val2',
  prop3: 'val3'
});

它也可以在 DS.Model 和其他Ember实体开箱即用,因为它们都扩展了 Ember.Object

It will also work on DS.Model and other Ember entities out of the box, since they all extend Ember.Object.

这篇关于Ember.Object实例中必需的属性(构造函数args)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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