我们构建了一个动态表单指令,该指令从服务器获取元数据,然后动态构建表单。渲染的输入绑定到与元数据分开的Model
对象。为了实现这一目标,我们正在做这样的事情:
<input type="field.Type"
ng-model="Model[field.Name]"
ng-repeat="field in metadata.Fields" />
假设上面的标记有效(嗯,它确实 - 在一个简单的场景中)并且绑定按预期工作。不幸的是,当我们使用的模型不是标量属性的集合时,它都会中断。例子包括:
正如您所看到的,当我有一个嵌套属性和/或当我有一个我需要绑定的列表时,会出现问题,这显然是一种正常行为,因为我们使用的是Model[propertyName]
表示法实现动态绑定。
我已经考虑过自己解析来自服务器的表达式并沿着模型的层次结构(嵌套属性)走下去并找出绑定,但是我无法正确(尚未)。此外,我仍然没有想到什么时候我将解决列表/数组绑定问题。
有什么想法吗?
答案 0 :(得分:2)
我不太确定您是否尝试从模型中获取列表属性,或者您是否尝试创建Dynamic Set Model?
对于不太困难的list属性,只需将数组附加到模型,甚至可以附加一个带有list属性的对象。
多个模型
或者您是否希望使用多个“模型”?
function MyCtrl($scope, $filter)
{
$scope.Model = {
SubModel : {
// Submodel stuff
},
FooModel : {
// Submodel stuff
}
}
}
编辑:
我完全错过了我第一次尝试的问题。问题确实想根据属性的类型呈现不同的内容(如果这不是你想要的我道歉)Plunker Example
HTML
<div ng-app ng-controller="MyCtrl">
<div ng-if="Configuration.hasLevels">
<div ng-repeat="lvl in Configuration.levels">
<input type="textbox" value="{{lvl.severity}}">
{{lvl.name}}
</div>
</div>
<div ng-if="!Configuration.hasLevels">
no levels: {{Configuration.levels}}
</div>
</div>
的JavaScript
function MyCtrl($scope, $filter)
{
// Configuration Object
$scope.Configuration = {
debug : true,
// Log Levels
levels : [
new Level("log", 0),
new Level("warning", 1),
new Level("error", 2)
]
// levels : "hello world"
};
$scope.Configuration.hasLevels = ($scope.Configuration.levels instanceof Array);
}
function Level(name, severity) { this.name = name; this.severity = severity; }
答案 1 :(得分:0)
所以我最终不得不在JavaScript代码中创建HTML而不是使用HTML模板......这样的事情:
FormBuilder.prototype.getAtomField = function (field) {
var self = this;
var atom = '<atom type="field.Type" name="field.Title" data-ng-show="field.Visible || evaluateExpression(field.VisibleIf)" hidevalidation="field.HideValidation" withlabel="field.WithLabel"'
+ 'datavalue="' + self.getDataValueBindingExpression(field.Name) + '" class="field.ClassName" required="field.Required || evaluateExpression(field.RequiredIf)"'
+ 'enabled="(field.Enabled || evaluateExpression(field.EnabledIf))" watermark="field.Watermark" orientation="field.Orientation" example="field.Example" modelkey="api.getFieldModelKey(field.Name)"'
+ 'min="field.Min" max="field.Max" description="field.Description" suggestedvalues="field.SuggestedValues" limittosuggestions="field.LimitToSuggestions" multiple="field.Multiple"'
+ 'displaypath="field.DisplayPath" valuepath="field.ValuePath" remoteurl="field.RemoteUrl" changehandler="invokeAction" changehandlerparam="field.ChangeHandler"'
+ 'source="field.Source" sourcefilter="field.SourceFilter" groupnamepath="field.GroupNamePath" disabledpath="field.DisabledPath" iconpath="field.IconPath"'
+ 'toggle="field.Toggle" formatresult="field.FormatResult" formatselection="field.FormatSelection" requestdatamapper="field.RequestDataMapper"'
+ 'responsedatamapper="field.ResponseDataMapper" pagelimit="field.PageLimit" remotedatatype="field.RemoteDataType" eagersearch="field.EagerSearch"'
+ 'numberofdigits="field.NumberOfDigits" step="field.Step" format="api.evaluateRegexExpression(field.Format, field.Type)"></atom>';
return atom;
};
请注意,atom
只是一个与表单字段等效的包装指令。执行此操作的部分是对self.getDataValueBindingExpression(field.Name)
的调用,它只是正确返回连接的字段名称:
FormBuilder.prototype.getDataValueBindingExpression = function (name) {
var self = this;
return 'api.description.Model.' + name;
};