我正在使用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 的解决方案。
非常感谢任何建议!
最佳答案
我过去在使用angular-schema-form-dynamic-select
时遇到了问题,并放弃了它,转而采用普通的解决方案,然后我不得不将其移植到angular6-json中-schema-form
当我们获得将项目从 AngularJS 迁移到 Angular 7 的许可时。虽然它确实需要相当多的苦力,但它允许您填充数据或在表单初始化中执行您想要的任何其他操作,仅具有普通模式表单。
在我的上下文中|异步
不是一个选项,因为由于我无法控制的原因,数据获取返回了 bluebird promise ,它与异步过滤器不兼容。如果您没有这个限制,我会先尝试看看@Mic 的建议是否有效。
我创建了一个助手来获取 Promise 的结果(在我的例子中是 HAL REST 列表端点)并将其转换为标题图。就我而言,我总是想要元素的名称
,或者如果失败的话,它的描述
,所以这就是我所采用的:
// 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
表示所有 Promise 均已解决,因此可以呈现表单而无需强制重绘:
<json-schema-form *ngIf="ready"
...
[form]="form"
...
>
</json-schema-form>
不像嵌入式扩展那么简洁,但也能完成工作。
关于Angular6 模式表单动态选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55148959/