Ember 在 Action 中集中处理错误
Ember centralised error handling within an Action
在一个 Ember controller
中,我有许多 actions
在商店中执行数据事件(创建更新和删除)。
这些请求中的每一个都有重复多次的相同错误处理逻辑。有没有办法集中这个错误逻辑?
- 鉴于此逻辑将被许多路由使用,Ember 中哪个位置最适合它运行?
- 如何保留上下文,以便
this
仍然可以向 DOM 发送 toast 类型的消息?
这是我现在的例子
createEntryRecord() {
// This action is a 'create' button on a modal
set(this, 'isLoadingModal', true); // shows loading spinner
let dbid = this.get('dbidModal');
let type = this.get('entryModalType');
this.get('store').createRecord('my-store', {
type,
dbid
})
.save()
.then((record) => {
get(this, 'flashMessages').success(`Created`); // Toast message
})
.catch((e) => {
// Begin of the error handling logic
let errors = get(e, 'errors');
if (errors.length) {
errors.forEach(err => {
let field = err.source.pointer.split("/").pop();
get(this, 'flashMessages').danger(`${field}: ${err.detail}`);
});
} else {
let message = get(e, 'message');
get(this, 'flashMessages').danger(`${message}`);
}
})
.finally(() => {
set(this, 'isLoadingModal', false); // stop the loading spinner
set(this, 'isEntryModalShown', false);
});
},
我建议使用 Ember 的对象模型 Mixins。
首先,您为所有模型创建一个通用的 Mixin:
// app/mixins/flashing-model.js
import Mixin from '@ember/object/mixin';
import { inject as service } from '@ember/service';
export default Mixin.create({
flashMessages: service(), // can be accessed via this.get('flashMessages')
save(...args) {
const superSavePromise = this._super(...args);
superSavePromise.then(() => {
// your positive logic
}).catch(e => {
// your negative logic
});
return superSavePromise;
}
});
然后将其包含在每个模型中。例如:
// app/models/some-model.js
import FlashingModel from '{your-app-name}/mixins/flashing-model';
import DS from 'ember-data'
export default DS.Model.extend(FlashingModel, {
// ...
});
之后你可以编辑你的控制器:
this.get('store').createRecord('my-store', {
type,
dbid
})
.save()
.finally(() => {
// ...
});
所以关于你的问题:
1. Ember Mixins(在 app/mixins
目录下)是存放通用逻辑的好地方。
2. 实施上述解决方案时,您实际上不需要保留控制器的 this
上下文,因为 flashMessages service 已注入每个模型。因此,您可以在 save
方法的上下文中访问该服务,即模型的 this
。
在一个 Ember controller
中,我有许多 actions
在商店中执行数据事件(创建更新和删除)。
这些请求中的每一个都有重复多次的相同错误处理逻辑。有没有办法集中这个错误逻辑?
- 鉴于此逻辑将被许多路由使用,Ember 中哪个位置最适合它运行?
- 如何保留上下文,以便
this
仍然可以向 DOM 发送 toast 类型的消息?
这是我现在的例子
createEntryRecord() {
// This action is a 'create' button on a modal
set(this, 'isLoadingModal', true); // shows loading spinner
let dbid = this.get('dbidModal');
let type = this.get('entryModalType');
this.get('store').createRecord('my-store', {
type,
dbid
})
.save()
.then((record) => {
get(this, 'flashMessages').success(`Created`); // Toast message
})
.catch((e) => {
// Begin of the error handling logic
let errors = get(e, 'errors');
if (errors.length) {
errors.forEach(err => {
let field = err.source.pointer.split("/").pop();
get(this, 'flashMessages').danger(`${field}: ${err.detail}`);
});
} else {
let message = get(e, 'message');
get(this, 'flashMessages').danger(`${message}`);
}
})
.finally(() => {
set(this, 'isLoadingModal', false); // stop the loading spinner
set(this, 'isEntryModalShown', false);
});
},
我建议使用 Ember 的对象模型 Mixins。
首先,您为所有模型创建一个通用的 Mixin:
// app/mixins/flashing-model.js
import Mixin from '@ember/object/mixin';
import { inject as service } from '@ember/service';
export default Mixin.create({
flashMessages: service(), // can be accessed via this.get('flashMessages')
save(...args) {
const superSavePromise = this._super(...args);
superSavePromise.then(() => {
// your positive logic
}).catch(e => {
// your negative logic
});
return superSavePromise;
}
});
然后将其包含在每个模型中。例如:
// app/models/some-model.js
import FlashingModel from '{your-app-name}/mixins/flashing-model';
import DS from 'ember-data'
export default DS.Model.extend(FlashingModel, {
// ...
});
之后你可以编辑你的控制器:
this.get('store').createRecord('my-store', {
type,
dbid
})
.save()
.finally(() => {
// ...
});
所以关于你的问题:
1. Ember Mixins(在 app/mixins
目录下)是存放通用逻辑的好地方。
2. 实施上述解决方案时,您实际上不需要保留控制器的 this
上下文,因为 flashMessages service 已注入每个模型。因此,您可以在 save
方法的上下文中访问该服务,即模型的 this
。