循环使用Angular JS

时间:2016-03-29 19:05:16

标签: javascript angularjs foreach

我是Angular JS的新手,我一直在尝试使用它构建一个演示ASP .Net MVC应用程序。 简单地说,我有一个国家列表,每个国家都有一个3个相关城市的列表

var myModule = angular
                .module("myModule", [])
                .controller("myController", function ($scope) {
                    var countries = [
                        {
                            name: "UK",
                            cities: [
                                    {name: "London"},
                                    {name: "Birmingham" },
                                    {name: "Manchestar" }
                            ],
                            flag: "/Images/UK.gif",
                            foundationDate: new Date("May 20,1916"),
                            likes: 0,
                            dislikes: 0
                        },
                        {   
                            name: "USA",
                            cities: [
                                    {name: "Los Angeles"},
                                    {name: "Houston"},
                                    {name: "Florida"},
                            ],
                            flag: "/Images/USA.png",
                            foundationDate: new Date("August 01,1887"),
                            likes: 0,
                            dislikes: 0
                        },
                        {
                            name: "INDIA",
                            cities: [
                                    { name: "Hyderabad" },
                                    { name: "Mumbai" },
                                    { name: "Kolkata" },
                            ],
                            flag: "/Images/INDIA.jpg",
                            foundationDate: new Date("August 15,1947"),
                            likes: 0,
                            dislikes: 0
                        }
                    ];

在我的视图页面中,我正在显示它们。

我有一个搜索文本框,可以搜索国家/地区名称以及城市名称。这样就有$ scope.search函数。

                    $scope.search = function (country) {
                        if ($scope.searchText == undefined) {
                            return true; 
                        }
                        angular.forEach(country.cities, function (item) {
                            if (item.name.toLowerCase().indexOf($scope.searchText.toLowerCase()) != -1) 
                                return true;
                        });
                        return false;
                    }
});

这是视图代码

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"  ng-app="myModule">
<head>
    <title></title>
    <script src="Scripts/angular.js"></script>
    <script src="Scripts/MyModuleScript.js"></script>
    <style>
        table, th, td {
            border-collapse:collapse;
            border:1px solid black;
        }
        th, td {
            text-align:center;
            vertical-align:middle;
        }
    </style>
</head>
<body  ng-controller="myController">
  Rows to display : <input type="number" step="1" min="0" max="3" ng-model="rowLimit" />
    <br />
    <br />
    Search : <input type="text" placeholder="Search Countries & Cities" ng-model="searchText" />
    <br />
    <br />
    <div>
        <table style="padding:5px">
            <thead>
                <tr>
                    <th>Country</th>
                    <th>City 1</th>
                    <th>City 2</th>
                    <th>City 3</th>
                    <th>Flag</th>
                    <th>Foundation Date</th>
                    <th>Likes</th>
                    <th>Dislikes</th>
                    <th colspan="2">Actions</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="country in countries | orderBy : '+foundationDate' | limitTo: rowLimit | filter : search">
                    <td>{{ country.name }}</td>
                    <td ng-repeat="city in country.cities">
                        {{ city.name }}
                    </td>
                    <td><img ng-src="{{ country.flag }}" style="height:100px;width:150px"/> </td>
                    <td>{{ country.foundationDate | date : "dd/MM/yyyy" }}</td>
                    <td>{{ country.likes }}</td>
                    <td>{{ country.dislikes }}</td>
                    <td><input type="button" value="Like" ng-click="incrementLikes(country)"</td>
                    <td><input type="button" value="Dislike" ng-click="incrementDislikes(country)"</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

但是搜索功能无法正常工作。 这是html视图页面的屏幕截图

enter image description here

我知道逻辑根本没有为搜索功能正确设计。 有人可以帮我解决一下吗?

2 个答案:

答案 0 :(得分:2)

假设正在调用搜索函数,则只返回过滤器的布尔值以搜索对象。由于您传递给过滤器的模型对象没有要搜索的布尔属性,因此不会产生任何结果。您要做的是根据过滤的模型过滤searchText的字符串值。

如果您只想明确搜索模型的城市名称,我建议将属性名称传递给过滤器。

<tr ng-repeat="country in countries | filter : {cities.name : searchText} : true | limitTo: rowLimit | orderBy : '+foundationDate'">

要搜索国家/地区和城市名称,我建议您创建自定义过滤器,并将过滤器传递给searchText模型。

[ModuleNameHere].filter('filterCountryCityNames', function() {
    return function(obj, searchValue) {
        var options = [];           

        if (searchValue === undefined || searchValue === null)
            return obj;
        searchValue = searchValue.toLowerCase();
        angular.forEach(obj, function(value) {

        var foundCity = value.cities.map(function(r) {
            return r.name.toLowerCase().indexOf(searchValue) >= 0;
        }).sort().pop();

        if (value.name.toLowerCase().indexOf(searchValue) >= 0 || foundCity) {
            options.push(value);
        }
    });
        return options;
    }
})

您可以像使用html标记中的内置Angular过滤器一样使用它。

<tr ng-repeat="country in countries | filterCountryCityNames : searchText | orderBy : '+foundationDate'| limitTo: rowLimit ">

答案 1 :(得分:1)

我认为您的问题可能只是您forEach中的匿名函数。它将返回true给匿名函数,但不返回外部函数$scope.search()。因此,不是直接从函数返回而是变量变量并在结尾返回,或者使用reduce而不是forEach。

 $scope.search = function (country) {
                    if ($scope.searchText == undefined) {
                        return true; 
                    }

                    if (country.name.toLowerCase().indexOf($scope.searchText.toLowerCase()) != -1)
                        return true;

                    var found = false;
                    angular.forEach(country.cities, function (item) {
                        if (item.name.toLowerCase().indexOf($scope.searchText.toLowerCase()) != -1) 
                            found = true;
                    });
                    return found;
                }