我有两个要在商店中使用的数据类(我没有写的业务逻辑)。我通过装饰来解决该商店中的问题。它们定义为:
// data classes; // these would be in separate file.
class PayRate {
/**
* @param {number} storeId The store id of the pay rate. (-1 for all)
* @param {number} empId The id of the employee. (-1 for all)
* @param {number} taskId The id of the task. (-1 for all)
* @param {Date} effectiveDate The date the payrate goes in effect.
* @param {number} rate The rate of pay.
*/
constructor(storeId, empId, taskId, effectiveDate, rate) {
this.StoreId = storeId || -1;
this.EmpId = empId || -1;
this.TaskId = taskId || -1;
this.EffectiveDate = effectiveDate ? new Date(effectiveDate) : new Date();
this.Rate = rate || 0.00;
this.OriginalObject = $.extend(true, {}, this);
}
/**
* Gets a readable version of the effective date.
* @returns {string} A -m/dd/yyyy representation of the effective date.
*/
GetReadableDate() {
return this.EffectiveDate.toLocaleDateString("en-US");
}
/**
* Gets a one line description of the pay rate.
* @returns {string} A string in the form of (date) - payrate.
*/
GetDescription() {
return `(${this.GetReadableDate()}) - $${this.Rate.toFixed(2)}`;
}
/**
* Gets a one line description of the pay rate.
* Does the exact same as GetDescription(), but is overload of Object.prototype.toString, which allows for stringification of Objects
* @returns {string} A string in the form of (date) - payrate.
*/
toString() {
return `(${this.GetReadableDate()}) - $${this.Rate.toFixed(2)}`;
}
/**
* Tells whether a pay rate was changed or not.
* @returns {boolean} A boolean saying whether or not the pay rate was changed.
*/
IsChanged() {
if (this.EffectiveDate.getTime() !== this.OriginalObject.EffectiveDate.getTime()) {
return true;
}
if (this.Rate != this.OriginalObject.Rate) {
return true;
}
if (this._deleted) {
return true;
}
return false;
}
/**
* Reverts the changes back to the original.
*/
RevertChanges() {
$.extend(true, this, this.OriginalObject);
}
}
mobx.decorate(PayRate, {
StoreId : mobx.observable,
EmpId : mobx.observable,
TaskId : mobx.observable,
EffectiveDate : mobx.observable,
Rate : mobx.observable,
})
class TaskObject {
/**
* @param {Task} task The task that is being kept track of.
* @param {PermissionLink[]} permissionLinks A list of permission links that are being kept track of.
* @param {PayRate[]} payrates A list of pay rates that are being kept track of.
*/
constructor(task, permissionLinks = [], payrates = []) {
this.Model = $.extend(true, {}, task);
this.Model.Type = 25;
this.PermissionLinks = $.extend(true, [], permissionLinks);
this.Payrates = $.extend(true, [], payrates);
this.OriginalObject = $.extend(true, {}, this);
}
/**
* Gives the dirty status of the task object.
* @returns {boolean} Tells whether or not the TaskObject has been changed.
*/
IsChanged() {
if (this.Model.Id == -1) {
return true;
}
if (this.Model.Name != this.OriginalObject.Model.Name) {
return true;
}
if (this.Model.GroupName != this.OriginalObject.Model.GroupName) {
return true;
}
if (this.Model.DescStr != this.OriginalObject.Model.DescStr) {
return true;
}
if (this.Model.IsActive != this.OriginalObject.Model.IsActive) {
return true;
}
if (this.PermissionLinks.length != this.OriginalObject.PermissionLinks.length) {
return true;
}
for (let i = 0; i < this.PermissionLinks.length; i++) {
const element = this.PermissionLinks[i];
const compElement = this.OriginalObject.PermissionLinks[i];
if (JSON.stringify(element) !== JSON.stringify(compElement)) {
return true;
}
}
for (let i = 0; i < this.Payrates.length; i++) {
const payrate = this.Payrates[i];
if (payrate.IsChanged()) {
return true;
}
}
return false
}
/**
* Reverts the changes that are on the task object.
* @returns {TaskObject} The TaskObject with its changes discarded.
*/
RevertChanges() {
this.Model = $.extend(true, {}, this.OriginalObject.Model);
this.PermissionLinks = $.extend(true, [], this.OriginalObject.PermissionLinks);
for (let i = 0; i < this.Payrates.length; i++) {
this.Payrates[i].RevertChanges()
}
return this;
}
/**
* This is here for debugging purposes (i.e. with data stores that use it) and may be overwritten with business logic at any time
*/
toString() {
return JSON.stringify(this, null, '\t')
}
}
// marking all the properties of TaskObject observable
mobx.decorate(TaskObject, {
Model : mobx.observable,
PermissionLinks : mobx.observable,
Payrates : mobx.observable,
RevertChanges : mobx.action,
IsChanged : mobx.computed
})
现在,执行new PayRate().IsChanged()
可以按预期工作,但是new TaskObject.IsChanged()
会导致:
Uncaught TypeError: Cannot read property 'call' of undefined
at e.computeValue (mobx.umd.min.js:1)
at e.get (mobx.umd.min.js:1)
at e.read (mobx.umd.min.js:1)
at TaskObject.get (mobx.umd.min.js:1)
at pen.js:163
e.computeValue @ mobx.umd.min.js:1
e.get @ mobx.umd.min.js:1
e.read @ mobx.umd.min.js:1
get @ mobx.umd.min.js:1
(anonymous) @ pen.js:163
为什么会这样,我该如何解决?
答案 0 :(得分:0)
您将IsChanged
声明为函数,但将其修饰为computed属性,然后将其调用为函数。如果希望将其作为计算属性,则需要:
IsChanged() -> get IsChanged()
new TaskObject.IsChanged()