我正在使用Angular6 JSON Schema Form
其中html select元素用json描述如下:
{
"schema": {
"type": "object",
"title": "My Form",
"properties": {
"select1552420741389": {
"type": "string"
}
},
"required": [
"select1552420741389"
]
},
"layout": [
{
"key": "select1552420741389",
"type": "select",
"multiple": false,
"notitle": false,
"title": "Select",
"titleMap": [
{
"name": "Option 1",
"value": "option1"
},
{
"name": "Option 2",
"value": "option2"
}
]
}
],
"data": {}
}我希望可以选择是通过自定义回调函数动态加载titleMap,还是指定要调用的URL来获取titleMap数据。
我见过用angular.js编写的库的下降,但我需要一个适用于Angular和Material的解决方案。
任何建议都非常感谢!
发布于 2019-03-15 02:31:05
我过去遇到过angular-schema-form-dynamic-select的问题,我放弃了它,转而采用普通的解决方案,当我们获得许可将项目从AngularJS迁移到Angular 7时,我不得不将其移植到angular6-json-schema-form中。虽然它确实需要相当多的体力,但它允许您在表单初始化中填充数据或执行其他任何您想做的事情,只使用普通的模式表单。
在我的上下文中,| async不是一个选项,因为由于我无法控制的原因,数据获取返回了bluebird promise,这与异步过滤器不兼容。如果你没有这个限制,我会先看看@Mic的建议是否有效。
我创建了一个帮助器来获取promise的结果(在我的例子中,是一个HAL REST列表端点),并将其转换为标题映射。在我的例子中,我总是想要元素的name,或者,如果不这样做,它的description,所以这就是我使用的:
// returns a [{name: name, value: link}, ...] mapping of items for form
// display based on a promise whose result is a list of entities
private formify(promise) {
return promise
.then(result => result._embedded[Object.keys(result._embedded)[0]].map(element => ({
name: element.name || element.description,
value: element._links.self.href
})))
.catch(error => console.log(error));
}然后是创建onInit回调的另一个帮助器:
// returns an onInit callback for a simple select that is populated with
// the list of entities supplied by the given promise
private getStandardPromiseOnInit(formItem, promise) {
return () => this.formify(promise)
.then(function(result) {
formItem.titleMap = result;
})
.catch(error => console.log(error));
}然后,我将一个onInit字段添加到我的表单项:
formItem.onInit = this.getStandardPromiseOnInit(formItem, callToRestService());在此之后,我的表单定义对象(它使用AngularJS语法,因为这是一个端口)将如下所示:
[
{
"key": "type",
"placeholder": "...",
"type": "select",
"onInit": <function....>
},
{
"key": "equipment",
"placeholder": "...",
"type": "select",
"onInit": <other function....>
},
...
]我有一个用于获取表单定义的服务,它可以完成这项工作。
然后,在初始化表单组件时,我递归地遍历表单声明,查找onInit回调并执行它们:
form: any;
ready: boolean;
ngOnInit() {
...
this.populateForm();
}
populateForm: Function = () => {
let onInits = [];
if (this.form) {
// recursively traverse the form json
let traverse = item => {
if (item.items) {
item.items.map(traverse);
} else if (item.tabs) {
item.tabs.map(traverse);
}
// call onInit callbacks
if (item.onInit) {
onInits.push(item.onInit());
}
};
this.form.map(traverse);
}
Promise.all(onInits)
.then(() => this.ready = true)
.catch(error => {
// error handling and message display
});
};this.ready表示所有承诺都已解决,因此无需强制重绘即可呈现表单:
<json-schema-form *ngIf="ready"
...
[form]="form"
...
>
</json-schema-form>虽然不像插件扩展那样简洁,但它确实很好用。
发布于 2019-03-14 02:47:58
我自己没有试过,但从readme看,绑定到[layout]="yourJsonFormLayout"属性,并根据您的需要更新yourJsonFormLayout将会起作用。
还可以使用| async管道从要查询的URL加载数据,并根据格式进行调整,如下所示
this.yourJsonFormLayout = http.get(...).pipe(map(...format your object...));https://stackoverflow.com/questions/55148959
复制相似问题