我的问题有点复杂,所以我会尽量详细解释。
我在SPA中有一个指令,它基于我从API获得的JSON数据来呈现它们的组件。基于元素及其类型(JSON是一个不同对象的数组),我将渲染特定指令中的每个对象:
指令类型1-2-3包含在父指令中,每个指令都有不同的控件(select,checkbox)。这是一个非常简单的草图:
和“子指令”:
我正在按以下方式渲染我的元素(Container directive
):
<div ng-repeat="element in elementList | customFilter:itemsType1">
<div class="line"></div>
<div class="form-group">
<directivetype1 itemdata="element" modeldata="data"></directivetype1>
</div>
</div>
<div ng-repeat="element in elementList | customFilter:itemsType2">
<div class="line"></div>
<div class="form-group">
<directivetype2 itemdata="element" modeldata="data"></directivetype2>
</div>
</div>
...
这是Directive 1
代码:
<div class="container-fluid">
<div class="form-group">
<div class="col-xs-6 col-sm-3">
<div class="checkbox">
<label><input type="checkbox"/>{{itemdata.metadata.description}}</label>
</div>
</div>
<div class="col-xs-6 col-sm-3">
<label>Option</label>
<select class="form-control" ng-model="" ng-options="list.id as list.label for list in item.optionData"></select>
</div>
</div>
</div>
当我尝试将模型附加到呈现的每个元素时,我的问题就出现了,因为:
数据具有以下结构:
查看数据:
[
{
"elementA": {
"metadata": {
"id": "001",
"subId": "016",
"description": "Element 1"
},
"optionData": [
{
"id": "5",
"label": "Option 1"
},
{
"id": "6",
"label": "Option 2"
},
{
"id": "7",
"label": "Option 3"
}
]
}
},
{
"elementB": {
"metadata": {
"id": "002",
"subId": "024",
"description": "Element 2"
},
"optionData": [
{
"id": "1",
"label": "Option 1"
},
{
"id": "2",
"label": "Option 2"
},
{
"id": "3",
"label": "Option 3"
}
]
}
}
]
模型数据:
[
{
"metadata": {
"id": "002",
"subId": "024",
"description": "Element 2",
"selected": "1"
},
...(Some other data belonging to the model)
},
{
"metadata": {
"id": "001",
"subId": "016",
"description": "Element 1",
"selected": "5"
},
...(Some other data belonging to the model)
},
...
]
正如您所看到的,关联这两种模型的唯一方法是使用id
对象中的subId
和metadata
字段(因为metadata
本身可能会有更多变化或更少的领域)。
问题
如何基于视图对象过滤我的模型对象?我的目标是获取与视图对象相关的模型对象,并将其传递给子指令,以将其设置为我在该点渲染的控件的模型。
修改:
正如cmw指出的那样,我编写了一个函数来将每个模型对象与它们各自的视图对象相关联,但该对象没有反映在指令范围内。 itemdata
和modeldata
使用双向范围('=')传递给指令。我认为(但我不完全确定)当我将函数传递给modeldata
时,该指令无法设置返回的对象。我根据cmw答案编写的解决方案如下:
指令:
<directivetype1 itemdata="element" modeldata="getModelObject(data)"></directivetype1>
JS(在父级的Ctrl中编码):
$scope.getModelObject = function(element){
var id = typeof element.metadata === 'undefined' ? null : element.metadata.id;
var subid = typeof element.metadata === 'undefined' ? null : element.metadata.subid;
var modelElement = null;
for (var i = 0; i < $scope.data.length; i += 1){
element = $scope.data[i];
if (modelElement.metadata.id === id && modelElement.metadata.subid === id) return element;
}
return null;
};
但是当我尝试使用modeldata
在指令中工作时,我在FF / Chrome控制台中看到“null”。
知道发生了什么的任何准则?
感谢。
编辑2:
我在这里添加了我的代码版本:http://plnkr.co/edit/xjp1l3PuWczdqYf5LP8q?p=preview。可悲的是,在Plunkr中它按预期工作但我的代码没有(我期望看到<h1>{{modeldata}}</h1>
的输出)。我正在比较两个版本以查看任何差异(请注意,我已经包含了我在项目中使用的相同AngularJS版本。)
答案 0 :(得分:0)
正如您所指出的,我认为关键是只使用id
对象上的subId
和meta
属性。
这样的事可能有用......
<div ng-repeat="element in elementList | customFilter:itemsType1">
<div class="line"></div>
<div class="form-group">
<directivetype1 itemdata="element" modeldata="modelDataFor(element)">
</directivetype1>
</div>
</div>
然后,在您的控制器中,定义如下的函数......
$scope.modelDataFor = function (element) {
var id = element.meta.id,
subId = element.meta.subId,
curr;
for (var i = 0; i < $scope.data.length; i += 1) {
curr = $scope.data[i];
if (curr.meta.id === id && curr.meta.subId === subId) {
return curr;
}
}
return null;
}
这似乎是将相关数据模型对象传递到嵌套指令的最自然的地方。