首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular6架构表单动态选择

Angular6架构表单动态选择
EN

Stack Overflow用户
提问于 2019-03-14 02:29:19
回答 2查看 968关注 0票数 2

我正在使用Angular6 JSON Schema Form

其中html select元素用json描述如下:

代码语言:javascript
复制
  {
"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的解决方案。

任何建议都非常感谢!

EN

回答 2

Stack Overflow用户

发布于 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,所以这就是我使用的:

代码语言:javascript
复制
  // 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回调的另一个帮助器:

代码语言:javascript
复制
  // 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字段添加到我的表单项:

代码语言:javascript
复制
  formItem.onInit = this.getStandardPromiseOnInit(formItem, callToRestService());

在此之后,我的表单定义对象(它使用AngularJS语法,因为这是一个端口)将如下所示:

代码语言:javascript
复制
[
  {
    "key": "type",
    "placeholder": "...",
    "type": "select",
    "onInit": <function....>
  },
  {
    "key": "equipment",
    "placeholder": "...",
    "type": "select",
    "onInit": <other function....>
  },
  ...
]

我有一个用于获取表单定义的服务,它可以完成这项工作。

然后,在初始化表单组件时,我递归地遍历表单声明,查找onInit回调并执行它们:

代码语言:javascript
复制
  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表示所有承诺都已解决,因此无需强制重绘即可呈现表单:

代码语言:javascript
复制
<json-schema-form *ngIf="ready"
    ...
    [form]="form" 
    ...
>
</json-schema-form>

虽然不像插件扩展那样简洁,但它确实很好用。

票数 2
EN

Stack Overflow用户

发布于 2019-03-14 02:47:58

我自己没有试过,但从readme看,绑定到[layout]="yourJsonFormLayout"属性,并根据您的需要更新yourJsonFormLayout将会起作用。

还可以使用| async管道从要查询的URL加载数据,并根据格式进行调整,如下所示

代码语言:javascript
复制
this.yourJsonFormLayout = http.get(...).pipe(map(...format your object...));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55148959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档