AngularJS——一个更简单的绑定一对一和一对多关系的方法
AngularJS - an easier way to bind one to one and one to many relationships?
我正在浏览angular教程,在那里你可以构建一个电话信息网站,同时我正在探索更复杂的数据结构,人们会在使用grails restful json服务的实际企业应用程序中看到;比如在Phone模型中添加一个一对一关系的外形因子,以及在一对多关系中添加多个覆盖Phone实体的专利。
是否有一种比下面更简单的方法将HTML绑定到不同的模型数据结构,这样一对一对和一对多关系就不需要使用非优雅的ng-repeat?
理想情况下,我想要一种比嵌套ng-repeat元素更简单的方法来获取formFactor的描述,并且在使用ng-repeat列出每个电话时,必须嵌套3个深度ng-repeat才能列出每个专利对象的子记录信息。
有比下面所示的更简单的方法吗?
这是angular化的HTML:
<div class="list-group">
<a href="#" class="list-group-item" ng-repeat="phone in phones | filter:query | orderBy:orderProp">
<h4 class="list-group-item-heading">{{phone.name}} <span ng-repeat="formFactor in formFactors | filter:phone.formFactor.id">({{formFactor.description}})</span></h4>
<p class="list-group-item-text">{{phone.snippet}}</p>
<hr />
<p><span class="list-group-item-heading">Patents covering phone:</span>
<ul class="list-group">
<li class="list-group-item" ng-repeat="phPat in phone.patents"><span ng-repeat="patent in patents | filter:{id:phPat.id}">{{patent.patentNumber + ': ' + patent.patentAbstract}}</span></li>
</ul>
</p>
</a>
</div>
这是angular控制器的代码:
var templateApp = angular.module('templateApp', []);
templateApp.controller('PhoneListCtrl', ['$scope', '$rootScope', '$http', '$location',
function($scope, $rootScope, $http, $location)
{
$http.get('phone/index').success(function(data)
{
$scope.phones = data;
});
$http.get('formFactors.json').success(function(data)
{
$scope.formFactors = data;
});
$http.get('formFactors.json').success(function(data)
{
$scope.formFactors = data;
});
$scope.orderProp = 'age';
}]);
这是web服务返回的JSON:电话/指数:
[
{
"class": "package.Phone",
"id": "12",
"age": 4,
"formFactor": {
"id": 10
},
"imageURL": "asdf",
"name": "Motorola DEFY with MOTOBLUR",
"patents": [
{
"id": 9
},
{
"id": 7
},
...
],
"snippet": "Are you ready for everything life throws your way?"
},
...
]
formFactors.json:
[
{
"id": 12,
"description": "tablet"
},
{
"id": 11,
"description": "smartphone"
},
...
]
patents.json:
[
{
"id": 9
"patentAbstract": "four score...",
"patentNumber": "789"
},
{
"id": 8
"patentAbstract": "lorem ipsum....",
"patentNumber": "456"
}
...
]
update:多亏了下面的答案,这就是我最终在控制器中编写的内容,因此所有数据都可以立即直接用于模板,因此我们不必做任何讨厌的三重嵌套ng-repeat:
angular.forEach($scope.phones, function(phone,i)
{
phone.formFactor = angular.findWhere($scope.formFactors, {id:phone.formFactor.id});
angular.forEach(phone.patents, function(phPat, i)
{
if(typeof phone.patentInfo == 'undefined')
{
phone.patentInfo = $filter('filter')($scope.patents, {id:phPat.id});
}
else
{
phone.patentInfo.push( $filter('filter')($scope.patents, {id:phPat.id})[0] );
}
});
});
我也遇到过这个问题,但实际上你在任何地方都遇到过这个问题,即uncore的答案是。findwhere,这样你就可以根据一些简单的标准从许多对象中派生出单个对象。如果我知道我需要在我的数据集或模板中这样做,我通常会提前循环,引用,然后设置这些数据,这样我就不必在模板中这样做了。
因此,如果你正在抓取手机,并且你知道你将需要引用另一个数组中的单个对象作为专利,甚至许多,请提前在javascript中进行过滤,并在每个手机上设置该对象或对象数组和属性,这样你就不需要在模板中做了。
。
$http.get('phone/index').success(function(data)
{
$scope.phones = data;
angular.forEach($scope.phones,function(phone,i) {
angular.forEach(phone.patents,function(phPat,i){
phone.phPat = $filter('filter')(phPat,{id:phPat.id});
});
});
});
我厌倦了做一个过滤器只是暴露一个对象,所以如果我知道它将是一个单一的对象在许多我使用这个findWhere函数我添加。
angular.findWhere = function(collection,search) {
var $filter = angular.element(document).injector().get("$filter"),
refined = $filter('filter')(collection,search);
return refined[0];
}
实际上,最终您需要从一开始就对数据的结构有更多的控制,这样您就不需要循环遍历一堆嵌套的数据来暴露数据
- 在VanillaJS中模拟模型双向数据绑定
- 无法通过数组映射绑定
- 主干-不管怎样,检查事件以前是否绑定过
- 用于搜索的聚合物嵌套绑定
- Angular:更新一次性绑定的数据
- 如何使用ngrepeat和双向绑定获得指令的隔离范围
- react.js中的密钥绑定
- 使用regex的jquery keydown绑定不会验证撇号和句点
- 将事件处理程序绑定到任何可能的事件
- AngularJS指令只识别双向绑定类型
- Telerik rad组合框多列数据绑定
- 对API数据使用声明性绑定
- 如何销毁/删除/取消绑定SnapSVG.js
- 在D3.js中,有没有任何方法可以将x和y方向上的滚动事件绑定到平移svg
- 数据绑定:'系统Char'不包含名为'xxxxx'
- react组件中的绑定方法
- 如何将ngrepeat下的ngmodel绑定到$scope
- WinJS内联绑定语法
- ng绑定和ng href问题.ng href未从控制器加载数据
- AngularJS——一个更简单的绑定一对一和一对多关系的方法