渲染Formio自定义组件不起作用

时间:2019-03-08 15:38:55

标签: javascript html angular typescript

我有一个formio js文件,例如checkbox.js,我将该组件注册到我的custom_formio组件中,如下所示...

checkbox.js

import _ from 'lodash';
import BaseComponent from 'formiojs/components/base/Base';

export default class CheckBoxComponent extends BaseComponent {
  static schema(...extend) {
    return BaseComponent.schema({
      type: 'checkbox',
      inputType: 'checkbox',
      label: 'Checkbox',
      key: 'checkbox',
      dataGridLabel: true,
      labelPosition: 'right',
      value: '',
      name: ''
    }, ...extend);
  }
 
  static get builderInfo() {
    return {
      title: 'Checkbox',
      group: 'basic',
      icon: 'fa fa-check-square',
      documentation: 'http://help.form.io/userguide/#checkbox',
      weight: 50,
      schema: CheckBoxComponent.schema()
    };
  }
 
  get defaultSchema() {
    return CheckBoxComponent.schema();
  }
 
  get defaultValue() {
    return this.component.name ? '' : (this.component.defaultValue || false).toString() === 'true';
  }
 
  get hasSetValue() {
    return this.hasValue();
  }
 
  elementInfo() {
    const info = super.elementInfo();
    info.type = 'input';
    info.changeEvent = 'click';
    info.attr.type = this.component.inputType || 'checkbox';
    info.attr.class = 'form-check-input';
    if (this.component.name) {
      info.attr.name = `data[${this.component.name}]`;
    }
    info.attr.value = this.component.value ? this.component.value : 0;
    return info;
  }
 
  build() {
    if (this.viewOnly) {
      return this.viewOnlyBuild();
    }
 
    if (!this.component.input) {
      return;
    }
    this.createElement();
    this.input = this.createInput(this.element);
    this.createLabel(this.element, this.input);
    if (!this.labelElement) {
      this.addInput(this.input, this.element);
    }
    this.createDescription(this.element);
    this.restoreValue();
    if (this.shouldDisable) {
      this.disabled = true;
    }
    this.autofocus();
    this.attachLogic();
  }
 
  get emptyValue() {
    return false;
  }
 
  isEmpty(value) {
    return super.isEmpty(value) || value === false;
  }
 
  createElement() {
    let className = `form-check ${this.className}`;
    if (!this.labelIsHidden()) {
      className += ` ${this.component.inputType || 'checkbox'}`;
    }
    this.element = this.ce('div', {
      id: this.id,
      class: className
    });
    this.element.component = this;
  }
 
  labelOnTheTopOrLeft() {
    return ['top', 'left'].includes(this.component.labelPosition);
  }
 
  labelOnTheTopOrBottom() {
    return ['top', 'bottom'].includes(this.component.labelPosition);
  }
 
  setInputLabelStyle(label) {
    if (this.component.labelPosition === 'left') {
      _.assign(label.style, {
        textAlign: 'center',
        paddingLeft: 0,
      });
    }
 
    if (this.labelOnTheTopOrBottom()) {
      _.assign(label.style, {
        display: 'block',
        textAlign: 'center',
        paddingLeft: 0,
      });
    }
  }
 
  setInputStyle(input) {
    if (!input) {
      return;
    }
    if (this.component.labelPosition === 'left') {
      _.assign(input.style, {
        position: 'initial',
        marginLeft: '7px'
      });
    }
 
    if (this.labelOnTheTopOrBottom()) {
      _.assign(input.style, {
        width: '100%',
        position: 'initial',
        marginLeft: 0
      });
    }
  }
 
  createLabel(container, input) {
    const isLabelHidden = this.labelIsHidden();
    let className = 'control-label form-check-label';
    if (this.component.input
      && !this.options.inputsOnly
      && this.component.validate
      && this.component.validate.required) {
      className += ' field-required';
    }
 
    this.labelElement = this.ce('label', {
      class: className
    });
    this.addShortcut();
 
    const labelOnTheTopOrOnTheLeft = this.labelOnTheTopOrLeft();
    if (!isLabelHidden) {
      // Create the SPAN around the textNode for better style hooks
      this.labelSpan = this.ce('span');
 
      if (this.info.attr.id) {
        this.labelElement.setAttribute('for', this.info.attr.id);
      }
    }
    if (!isLabelHidden && labelOnTheTopOrOnTheLeft) {
      this.setInputLabelStyle(this.labelElement);
      this.setInputStyle(input);
      this.labelSpan.appendChild(this.text(this.component.label));
      this.labelElement.appendChild(this.labelSpan);
    }
    this.addInput(input, this.labelElement);
    if (!isLabelHidden && !labelOnTheTopOrOnTheLeft) {
      this.setInputLabelStyle(this.labelElement);
      this.setInputStyle(input);
      this.labelSpan.appendChild(this.text(this.addShortcutToLabel()));
      this.labelElement.appendChild(this.labelSpan);
    }
    this.createTooltip(this.labelElement);
    container.appendChild(this.labelElement);
  }
 
  createInput(container) {
    if (!this.component.input) {
      return;
    }
    const input = this.ce(this.info.type, this.info.attr);
    this.errorContainer = container;
    return input;
  }
 
  set dataValue(value) {
    const setValue = (super.dataValue = value);
    if (this.component.name) {
      _.set(this.data, this.component.key, setValue === this.component.value);
    }
    return setValue;
  }
 
  get dataValue() {
    const getValue = super.dataValue;
    if (this.component.name) {
      _.set(this.data, this.component.key, getValue === this.component.value);
    }
    return getValue;
  }
 
  get key() {
    return this.component.name ? this.component.name : super.key;
  }
 
  getValueAt(index) {
    if (this.component.name) {
      return this.inputs[index].checked ? this.component.value : '';
    }
    return !!this.inputs[index].checked;
  }
 
  getValue() {
    const value = super.getValue();
    if (this.component.name) {
      return value ? this.setCheckedState(value) : this.setCheckedState(this.dataValue);
    }
    else {
      return value;
    }
  }
 
  setCheckedState(value) {
    if (!this.input) {
      return;
    }
    if (this.component.name) {
      this.input.value = (value === this.component.value) ? this.component.value : 0;
      this.input.checked = (value === this.component.value) ? 1 : 0;
    }
    else if (value === 'on') {
      this.input.value = 1;
      this.input.checked = 1;
    }
    else if (value === 'off') {
      this.input.value = 0;
      this.input.checked = 0;
    }
    else if (value) {
      this.input.value = 1;
      this.input.checked = 1;
    }
    else {
      this.input.value = 0;
      this.input.checked = 0;
    }
    if (this.input.checked) {
      this.input.setAttribute('checked', true);
    }
    else {
      this.input.removeAttribute('checked');
    }
    return value;
  }
 
  setValue(value, flags) {
    flags = this.getFlags.apply(this, arguments);
    if (this.setCheckedState(value) !== undefined) {
      return this.updateValue(flags);
    }
  }
 
  getView(value) {
    return value ? 'Yes' : 'No';
  }
 
  destroy() {
    super.destroy();
    this.removeShortcut();
  }
}

custom_formio.component.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { FormioAuthService } from 'angular-formio/auth';
import { Formio } from 'formiojs';
import { CheckBoxComponent }from './Checkbox'
@Component({
  selector: 'app-custom_formio',
  templateUrl: './custom_formio.component.html',
  styleUrls: ['./custom_formio.component.less']
})
export class CustomFormioComponent  {
  title = 'app';
  offlineCount = 0;
  offlineMode: any = null;
  offlineError = '';
  constructor(private auth: FormioAuthService, private router: Router) {
    this.auth.onLogin.subscribe(() => {
      this.router.navigate(['/home']);
    });

    this.auth.onLogout.subscribe(() => {
      this.router.navigate(['/auth/login']);
    });

    this.auth.onRegister.subscribe(() => {
      this.router.navigate(['/home']); 
    });
    Formio.registerComponent('custom_formio', CheckBoxComponent);
  }
}

但是我不知道我必须在custom_formio.component.html中编写什么代码才能将自定义复选框组件呈现到我的应用程序中。

custom_formio.component.html

    <div class="m-content">
        <div class="m-portlet m-portlet--mobile">
            <div class="m-portlet__body">
                    <div id="custom_formio"></div>  
                </div>
        </div>
    </div>
    

但是它不起作用,有谁可以帮忙...

1 个答案:

答案 0 :(得分:0)

ES5类CheckBoxComponent应该包含您要使用超级类Build()方法BaseComponentrenderTemplate()中提供的自定义HTML。

自定义formio组件应使用本机html创建,因此您不能使用角度组件。

但是,有一种使用新角度功能的解决方案(角度元素又称网络组件)

签出avan2s的有角项目 https://github.com/avan2s/angular-app-starterkit

有用:https://github.com/formio/angular-formio/issues/201