动态输入编译
Dynamic input compilation
我尝试根据返回的对象服务器动态构建输入。
我使用 angularJS 指令。
由于对象是树状的,所以我使用了递归。
生成的问题不要绑定模型。
HTML:
<div ng-app="dyno">
<div ng-controller="fieldCompilation">
<br><br><b> Directive Inputs 1 (param via attr):</b><br>
<form action="" name="myForm1" novalidate>
<div ng-repeat="(itbl, tbl) in from1">
<div ng-repeat="(irec, rec) in tbl">
<div ng-repeat="(iel, el) in rec">
<build-fields1 list="el"></build-fields1>
</div>
</div>
</div>
Form validity: {{myForm1.$valid}}<br>
Model: {{from1[1][1061][0].value}}
</form>
<br>
</div>
</div>
JS:
app = angular.module('dyno', []);
app.directive('buildFields1', ['$compile',
function($compile) {
return {
restrict: 'E',
scope: {
list: '=list'
},
link: function(scope, element, attr) {
var e = scope.list;
switch (e.tagName) {
case 'input':
element.append(e.label + ' <' + e.tagName + ' name="' + e.name + '" placeholder="' + e.attrs.toString() + '" type="text" ng-change="' + e.func + '(' + e.param + ')" ng-model="' + e.value + '" ' + e.attrs.toString() + '>');
break;
case 'select':
element.append(e.label + '<' + e.tagName + ' name="'+e.name+'" ng-change="'+e.func+'(-2)" ng-model="'+e.name+'" ng-options="x.id as x.name for x in '+e.items.toString()+'">');
break;
case 'ref':
element.append('<div ng-repeat="(itbl, tbl) in $parent.' + e.value + '"><div ng-repeat="(irec, rec) in tbl"><div ng-repeat="(iel, el) in rec"><build-fields1 list="el"></build-fields1></div></div></div>');
break;
}
$compile(element.contents())(scope);
}
};
}
]);
app.controller('fieldCompilation', function($scope) {
var i;
// FORM2
// FORM1
$scope.from1 = [{}];
$scope.from1[1] = {};
$scope.from1[1][1061] = {};
i = 0;
$scope.from1[1][1061][i++] = {
tagName: 'input',
name: 'tid',
label: 'TID:',
attrs: ["required pattern='[0-9]{8}'"],
func: 'show',
param: '20',
value: '20000000',
};
$scope.from1[1][1061][i++] = {
tagName: 'input',
name: 'mid',
label: 'MID:',
attrs: ["required pattern='[0-9]{15}'"],
func: 'show',
param: '20',
value: '123456789012345',
};
$scope.from1[1][1061][i++] = {
tagName: 'select',
name: 'sel',
label: 'Class:',
attrs: [],
items: "[{id:'1',name:'A'},{id:'2',name:'B'},{id:'3',name:'C'}]",
func: 'show',
};
$scope.from1[1][1061][i++] = {
tagName: 'ref',
name: 'ref',
label: 'Ref:',
attrs: ["required pattern='[0-9]{8}'"],
func: 'show',
param: '1', // of function
value: 'from2',
};
$scope.from2 = [{}];
$scope.from2[2] = {};
$scope.from2[2][10] = {};
i = 0;
$scope.from2[2][10][i++] = {
tagName: 'input',
name: 'a',
label: 'A:',
attrs: ["required pattern='[0-9]{8}'"],
func: 'show',
param: '20',
value: '10000001',
};
$scope.from2[2][10][i++] = {
tagName: 'input',
name: 'b',
label: 'B:',
attrs: ["required pattern='[0-9]{15}'"],
func: 'show',
param: '20',
value: '882277441115599',
};
$scope.from2[2][10][i++] = {
tagName: 'select',
name: 'c',
label: 'C:',
attrs: [],
items: "[{id:'1',name:'a'},{id:'2',name:'b'},{id:'3',name:'c'}]",
func: 'show',
};
});
预期结果是:当我在 (f.e.TID) 中输入内容时,它的模型应该相应地改变。
现在我得到一个固定值,其中根本无法更改。
Fiddle
换行
element.append(e.label + ' <' + e.tagName + ' name="' + e.name
+ '" placeholder="' + e.attrs.toString() + '" type="text" ng-change="'
+ e.func + '(' + e.param + ')" ng-model="' + e.value + '" '
+ e.attrs.toString() + '>');
到
element.append(e.label + ' <' + e.tagName + ' name="' + e.name
+ '" placeholder="' + e.attrs.toString() + '" type="text" ng-change="'
+ e.func + '(' + e.param + ')" ng-model="list.value" '
+ e.attrs.toString() + '>');
如果您调试代码并查看编译后的实际值:
<input name="tid" placeholder="required pattern='[0-9]{8}'" type="text"
ng-change="show(20)" ng-model="20000000" required=""
pattern="[0-9]{8}"
class="ng-pristine ng-valid ng-scope ng-valid-required ng-valid-pattern ng-touched">
请注意 ng-model="2000000"
,这就是您永远无法更改它的原因。因为您正在编译它,所以您希望范围内的值 ng-model="list.value"
为 $scope.list.value
,因此可以被 ng-model 接受。
我尝试根据返回的对象服务器动态构建输入。 我使用 angularJS 指令。 由于对象是树状的,所以我使用了递归。
生成的问题不要绑定模型。
HTML:
<div ng-app="dyno">
<div ng-controller="fieldCompilation">
<br><br><b> Directive Inputs 1 (param via attr):</b><br>
<form action="" name="myForm1" novalidate>
<div ng-repeat="(itbl, tbl) in from1">
<div ng-repeat="(irec, rec) in tbl">
<div ng-repeat="(iel, el) in rec">
<build-fields1 list="el"></build-fields1>
</div>
</div>
</div>
Form validity: {{myForm1.$valid}}<br>
Model: {{from1[1][1061][0].value}}
</form>
<br>
</div>
</div>
JS:
app = angular.module('dyno', []);
app.directive('buildFields1', ['$compile',
function($compile) {
return {
restrict: 'E',
scope: {
list: '=list'
},
link: function(scope, element, attr) {
var e = scope.list;
switch (e.tagName) {
case 'input':
element.append(e.label + ' <' + e.tagName + ' name="' + e.name + '" placeholder="' + e.attrs.toString() + '" type="text" ng-change="' + e.func + '(' + e.param + ')" ng-model="' + e.value + '" ' + e.attrs.toString() + '>');
break;
case 'select':
element.append(e.label + '<' + e.tagName + ' name="'+e.name+'" ng-change="'+e.func+'(-2)" ng-model="'+e.name+'" ng-options="x.id as x.name for x in '+e.items.toString()+'">');
break;
case 'ref':
element.append('<div ng-repeat="(itbl, tbl) in $parent.' + e.value + '"><div ng-repeat="(irec, rec) in tbl"><div ng-repeat="(iel, el) in rec"><build-fields1 list="el"></build-fields1></div></div></div>');
break;
}
$compile(element.contents())(scope);
}
};
}
]);
app.controller('fieldCompilation', function($scope) {
var i;
// FORM2
// FORM1
$scope.from1 = [{}];
$scope.from1[1] = {};
$scope.from1[1][1061] = {};
i = 0;
$scope.from1[1][1061][i++] = {
tagName: 'input',
name: 'tid',
label: 'TID:',
attrs: ["required pattern='[0-9]{8}'"],
func: 'show',
param: '20',
value: '20000000',
};
$scope.from1[1][1061][i++] = {
tagName: 'input',
name: 'mid',
label: 'MID:',
attrs: ["required pattern='[0-9]{15}'"],
func: 'show',
param: '20',
value: '123456789012345',
};
$scope.from1[1][1061][i++] = {
tagName: 'select',
name: 'sel',
label: 'Class:',
attrs: [],
items: "[{id:'1',name:'A'},{id:'2',name:'B'},{id:'3',name:'C'}]",
func: 'show',
};
$scope.from1[1][1061][i++] = {
tagName: 'ref',
name: 'ref',
label: 'Ref:',
attrs: ["required pattern='[0-9]{8}'"],
func: 'show',
param: '1', // of function
value: 'from2',
};
$scope.from2 = [{}];
$scope.from2[2] = {};
$scope.from2[2][10] = {};
i = 0;
$scope.from2[2][10][i++] = {
tagName: 'input',
name: 'a',
label: 'A:',
attrs: ["required pattern='[0-9]{8}'"],
func: 'show',
param: '20',
value: '10000001',
};
$scope.from2[2][10][i++] = {
tagName: 'input',
name: 'b',
label: 'B:',
attrs: ["required pattern='[0-9]{15}'"],
func: 'show',
param: '20',
value: '882277441115599',
};
$scope.from2[2][10][i++] = {
tagName: 'select',
name: 'c',
label: 'C:',
attrs: [],
items: "[{id:'1',name:'a'},{id:'2',name:'b'},{id:'3',name:'c'}]",
func: 'show',
};
});
预期结果是:当我在 (f.e.TID) 中输入内容时,它的模型应该相应地改变。 现在我得到一个固定值,其中根本无法更改。 Fiddle
换行
element.append(e.label + ' <' + e.tagName + ' name="' + e.name
+ '" placeholder="' + e.attrs.toString() + '" type="text" ng-change="'
+ e.func + '(' + e.param + ')" ng-model="' + e.value + '" '
+ e.attrs.toString() + '>');
到
element.append(e.label + ' <' + e.tagName + ' name="' + e.name
+ '" placeholder="' + e.attrs.toString() + '" type="text" ng-change="'
+ e.func + '(' + e.param + ')" ng-model="list.value" '
+ e.attrs.toString() + '>');
如果您调试代码并查看编译后的实际值:
<input name="tid" placeholder="required pattern='[0-9]{8}'" type="text"
ng-change="show(20)" ng-model="20000000" required=""
pattern="[0-9]{8}"
class="ng-pristine ng-valid ng-scope ng-valid-required ng-valid-pattern ng-touched">
请注意 ng-model="2000000"
,这就是您永远无法更改它的原因。因为您正在编译它,所以您希望范围内的值 ng-model="list.value"
为 $scope.list.value
,因此可以被 ng-model 接受。