AngularJS——一个更简单的绑定一对一和一对多关系的方法

AngularJS - an easier way to bind one to one and one to many relationships?

本文关键字:一对一 绑定 关系 方法 一对多 更简单 一个 AngularJS      更新时间:2023-09-26

我正在浏览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];
}

实际上,最终您需要从一开始就对数据的结构有更多的控制,这样您就不需要循环遍历一堆嵌套的数据来暴露数据