【问题标题】:Looping in Angular JSAngular JS 中的循环
【发布时间】:2016-03-29 19:05:15
【问题描述】:

我是 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视图页面的截图

不知何故,我知道 search 功能的逻辑设计并不正确。 有人可以帮我解决吗?

【问题讨论】:

  • 过滤器:搜索文本,而不是搜索。它与您的 ng-model 匹配
  • 其实没有。我已经搜索了整个国家/地区名称,并且城市名称也与该国家/地区相关联。所以 $scope.search 就在那里。
  • 另外,佛罗里达不是一个城市,而是一个州
  • 从技术上讲,有一个佛罗里达州,俄亥俄州,但是是的,它主要被称为一个州。
  • 对不起,我不好。这根本不是故意的。

标签: javascript angularjs foreach


【解决方案1】:

假设正在调用搜索函数,您只返回一个布尔值供过滤器搜索对象。由于您传递给过滤器的模型对象没有要搜索的布尔属性,因此不会产生任何结果。您要做的是根据过滤后的模型过滤 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 ">

【讨论】:

  • 他需要城市和州。
  • @Vance Rivera 我完全理解你想要实现的目标,但有点好奇第一个参数 obj 是做什么用的?您只发送 searchText 参数对吗?那为什么是第一个参数呢?
  • 第一个参数是您要过滤的模型 obj。 Angular 会自动将模型传递给过滤器。冒号后面的任何内容都是您要传递的额外参数,但过滤器本质上会传递您要过滤的 obj。
  • @LukaJacobowitz,你是正确的卢卡,但你的答案也没有搜索这个国家。新的更新看起来像它的作品。不过我已经为你更新了。
  • 好处是您可以在此应用程序中的任何视图上重复使用此过滤器。
【解决方案2】:

我认为您的问题可能只是您 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;
                }

【讨论】:

  • 但这会搜索所有列对吗?
  • 你能帮忙吗?我对此没有太多想法。我才刚刚开始。
  • 这有帮助。是的,感谢您指出我犯错的地方。
  • 抱歉拖了这么久!
  • 没问题先生 :) 非常感谢您的努力。
猜你喜欢
  • 2015-11-27
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多