使用元数据在angular2中创建动态表单
发布时间:2020-12-17 17:25:27 所属栏目:安全 来源:网络整理
导读:我正在尝试使用元数据创建CRUD表单.我创建的是自定义组件的一个非常基本的版本,它从模型创建一个表单.但是,此时自定义表单不会更新父模型. 如何处理从伟大控件(请参阅代码)到父级的更改流程?我认为我需要的是像ng-model指令这样的功能.让解决方案可扩展以允
我正在尝试使用元数据创建CRUD表单.我创建的是自定义组件的一个非常基本的版本,它从模型创建一个表单.但是,此时自定义表单不会更新父模型.
如何处理从伟大控件(请参阅代码)到父级的更改流程?我认为我需要的是像ng-model指令这样的功能.让解决方案可扩展以允许验证会很好. 动态表单的基本版本:http://plnkr.co/edit/BW6hluJ0PZG5GF5gsO6G?p=preview import {Component,View,bootstrap,CORE_DIRECTIVES} from 'angular2/angular2'; import {FORM_DIRECTIVES,FORM_BINDINGS,NgFormModel,ControlGroup,Control,Validators} from 'angular2/forms'; @Component({selector: 'great-control',properties: ['column','value: data']}) @View({ template: ` <template [ng-if]="column.visible"> <div class="pure-control-group"> <span [ng-switch]="htmlElementType"> <template [ng-switch-when]="'input'"> <label [attr.for]="column.name">{{column.display}}</label> <input id="column.name" [attr.type]="computeInputSubType()" [(ng-model)]="value" [attr.placeholder]="column.display"> {{value}} </template> <template [ng-switch-when]="'checkbox'"> <div class="pure-controls"> <label for="column.name" class="pure-checkbox"> <input id="column.name" type="checkbox" [(ng-model)]="value"> Toggle and see the change {{value}} </label> </div> </template> <template [ng-switch-when]="'option'"> <label [attr.for]="column.name">{{column.display}}</label> <select [(ng-model)]="value"> <option *ng-for="#key of column.values" [value]="key">{{key}}</option> </select>{{value}} </div> </template> <template [ng-switch-default]"> <span>Oops! This control type is unknown. Contact the creator</span> </template> </span> </div> </template> <template [ng-if]="!column.visible"> There is a hidden control here because the column is set to invisible <input type="hidden" [(ng-model)]="value" /> </template> `,directives: [FORM_DIRECTIVES,CORE_DIRECTIVES] }) class GreatControl { column: Object; value: Object; htmlElementType:string; constructor() { } onInit(){ this.htmlElementType = this.computeHtmlElementType(); } computeHtmlElementType(): string { if (this.column.type == "boolean") { return "checkbox"; } else if (this.column.type == "enum") { return "option"; } else if (this.column.type == "text" || this.column.type == "email" || this.column.type == "number"){ return "input" }else{ return "unknown" } } computeInputSubType(){ if(this.column.type == "text"){ return "text"; } else if(this.column.type == "email"){ return "email"; } else if( this.column.type == "number"){ return "number"; } else { return "text"; } } } @Component({ selector: 'app',bindings: [FORM_BINDINGS] }) @View({ template: ` <div class="pure-g"><div class="pure-u-1-1"> <form [ng-form-model]='form' class="pure-form pure-form-aligned"> <fieldset> <great-control *ng-for="#t of columns" [column]="t" [data]="data[t.name]" > </great-control> <div class="pure-controls"> <button type="submit" class="pure-button pure-button-primary">Submit</button> </div> </fieldset> </form> </div><div class="pure-u-1-1"><p> As of now this does not change. We need it to change <br><pre>{{dataString()}}</pre></p></div></div>`,CORE_DIRECTIVES,GreatControl] }) class App { data: Object ; columns = [ {name: "column1",display:"This is number only",visible:true,type: "number",length:"10"},{name: "column2",display:"This a text field",type: "text",{name: "column3",display:"Column 3",visible:false,{name: "column4",display:"Toggle and see",type: "boolean"},{name: "column5",display:"Column 5",type: "enum",values:[ "Blue","Yellow","White"]} ]; constructor() { this.data= { column1 : "10",column3: "Not a secret",column4: false,column5: "Yellow" }; } onSubmit(f) { console.log(this.data); } dataString(){ return JSON.stringify(this.data,null,2); } valueOf(obj) { if (obj !== undefined && obj !== null) return obj; else return ""; } } bootstrap(App); 预期行为(非动态):http://plnkr.co/edit/kQ0sMT4jItvj3e5uLHtD?p=preview import {Component,NgIf,Validators} from 'angular2/forms'; @Component({ selector: 'app',bindings: [FORM_BINDINGS] }) @View({ template: ` <div class="pure-g"><div class="pure-u-1-1"> <form [ng-form-model]='form' class="pure-form pure-form-aligned"> <fieldset> <div class="pure-control-group"> <label [attr.for]="columns[0].name">{{columns[0].display}}</label> <input id="columns[0].name" type="number" [(ng-model)]="data[columns[0].name]" [attr.placeholder]="columns[0].display"> </div> <div class="pure-control-group"> <label [attr.for]="columns[1].name">{{columns[1].display}}</label> <input id="columns[1].name" type="text" [(ng-model)]="data[columns[1].name]" [attr.placeholder]="columns[1].display"> </div> <div class="pure-control-group"> There is a hidden control here because the column is set to invisible <input type="hidden" [(ng-model)]="data[columns[2].name]" /> </div> <div class="pure-controls"> <label for="columns[3].name" class="pure-checkbox"> <input id="columns[3].name" type="checkbox" [(ng-model)]="data[columns[3].name]"> Toggle and see the change </label> </div> <div class="pure-control-group"> <label [attr.for]="columns[4].name">{{columns[4].display}}</label> <select [(ng-model)]="data[columns[4].name]"> <option *ng-for="#state of columns[4].values" [value]="state">{{state}}</option> </select> </div> <div class="pure-controls"> <button type="submit" class="pure-button pure-button-primary">Submit</button> </div> </fieldset> </form> </div><div class="pure-u-1-1"><p><pre>{{dataString()}}</pre></p></div></div>`,CORE_DIRECTIVES] }) class App { data: Object ; columns = [ {name: "column1",2); } valueOf(obj) { if (obj !== undefined && obj !== null) return obj; else return ""; } } bootstrap(App); 任何解决这个问题的指针都非常感谢. 解决方法
您需要将值包装在对象中.
原始类型(字符串,数字,布尔值和公式)通过值传递(值被复制),然后通过引用传递对象实例(复制对象的引用). 这是一个更新的plunker: export class Value { value: any; constructor(value) { this.value = value; } } @Component({selector: 'great-control','value: data']}) @View({ template: ` <template [ng-if]="column.visible && value != null"> <div class="pure-control-group"> <span [ng-switch]="htmlElementType"> <template [ng-switch-when]="'input'"> <label [attr.for]="column.name">{{column.display}}</label> <input id="column.name" [attr.type]="computeInputSubType()" [(ng-model)]="value.value" [attr.placeholder]="column.display"> {{value.value}} </template> <template [ng-switch-when]="'checkbox'"> <div class="pure-controls"> <label for="column.name" class="pure-checkbox"> <input id="column.name" type="checkbox" [(ng-model)]="value.value"> Toggle and see the change {{value.value}} </label> </div> </template> <template [ng-switch-when]="'option'"> <label [attr.for]="column.name">{{column.display}}</label> <select [(ng-model)]="value.value"> <option *ng-for="#key of column.values" [value]="key">{{key}}</option> </select>{{value.value}} </div> </template> <template [ng-switch-default]"> <span>Oops! This control type is unknown. Contact the creator</span> </template> </span> </div> </template> <template [ng-if]="!column.visible"> There is a hidden control here because the column is set to invisible <input type="hidden" [(ng-model)]="value.value" /> </template> `,CORE_DIRECTIVES] }) class GreatControl { column: Object; value: Value; htmlElementType:string; constructor() { } onInit(){ this.htmlElementType = this.computeHtmlElementType(); } computeHtmlElementType(): string { if (this.column.type == "boolean") { return "checkbox"; } else if (this.column.type == "enum") { return "option"; } else if (this.column.type == "text" || this.column.type == "email" || this.column.type == "number"){ return "input" }else{ return "unknown" } } computeInputSubType(){ if(this.column.type == "text"){ return "text"; } else if(this.column.type == "email"){ return "email"; } else if( this.column.type == "number"){ return "number"; } else { return "text"; } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |