powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / HTML, JavaScript, VBScript, CSS [игнор отключен] [закрыт для гостей] / AngularJS нетривиальный фильтр
4 сообщений из 4, страница 1 из 1
AngularJS нетривиальный фильтр
    #38978606
D0KX
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем доброго дня.

Сижу ломаю голову вот над такой задачкой, переложенной на тестовый пример из AngularJS ng-repeat

Есть список друзей, и к нему прикручен какой-то фильтр (в данном случае по всему тексту, из input), но хочется так же фильтровать еще по каким-либо параметрам, например при установке галочки "Только девушки", производить фильтр по gender:'girl', а если галочка не стоит, использовать весь массив
Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
                            <div ng-init="friends = [
                              {name:'John', age:25, gender:'boy'},
                                {name:'Jessie', age:30, gender:'girl'},
                                {name:'Johanna', age:28, gender:'girl'},
                                {name:'Joy', age:15, gender:'girl'},
                                {name:'Mary', age:28, gender:'girl'},
                                {name:'Peter', age:95, gender:'boy'},
                                {name:'Sebastian', age:50, gender:'boy'},
                                {name:'Erika', age:27, gender:'girl'},
                                {name:'Patrick', age:40, gender:'boy'},
                                {name:'Samantha', age:60, gender:'girl'}
                                ]">
                                I have {{friends.length}} friends. They are:
                                <input type="search" ng-model="q" placeholder="Фильтр друзей..." aria-label="Фильтр друзей" />
                                <input type="checkbox" ng-model="a" aria-label="Только девушки">Только девушки...
                                <ul>
                                    <li ng-repeat="friend in results = friends | filter:q">
                                        [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
                                    </li>
                                    <li ng-if="results.length == 0">
                                        <strong>No results found...</strong>
                                    </li>
                                </ul>
                            </div>



Так вот, как можно добавить фильтр чтобы он срабатывал только когда чекбокс включен? Кроме варианта с ng-if, так как хотелось бы получить более изящное решение.
Использовать сложный фильтр как функцию и передавать значение ng-model="a" параметром, например так <li ng-repeat="friend in results = friends | filter:q | filter:myFunction(a)"> , но тогда как в этой функции получить объект friend который должен проверяться на условие фильтра.

Второй вариант очень заманчив, так как можно передавать сразу много параметров и делать очень сложную логику фильтра, но вот все никак не могу придумать как получить текущий friend
...
Рейтинг: 0 / 0
AngularJS нетривиальный фильтр
    #38978613
Фотография FishHook
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
app.filter('friends', function () {
  return function (items, some_attr_1, some_attr_2) {
    if  (some_attr_1){
         return [...]
    }
    return items;
  };
});



Код: html
1.
2.
3.
<input type="checkbox" ng-model="attr1" aria-label="Только девушки">Только девушки...
....
<li ng-repeat="friend in results | friends:attr1:attr2">
...
Рейтинг: 0 / 0
AngularJS нетривиальный фильтр
    #38980690
D0KX
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да в этом решении можно передать несколько аргументов для работы с ними, но есть и минусы....
1) каждый следующий фильтр надо добавлять так же к самому модулю
2) самое важное, что в этом варианте сложно получить объекты из $scope

Вообще у меня получилось развить эту мыслю и раз и навсегда решить эту проблему.

Вот что у меня получилось:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
<!DOCTYPE html>
 <html lang="ru" ng-app="app" class="no-js">
<head lang="ru">
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <!-- использовать режим совместимости последней версии ИЕ -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Портал Гос Услуг Камчатского края</title>

    <script src="js/angular/1.2.26/angular.js"></script>
    <script src="js/angular/controller2.js"></script>

</head>
<body class="body" ng-controller="appMain" id="a1">
    <div ng-init="friends = [
                                  {name:'John', age:25, gender:'boy'},
                                    {name:'Jessie', age:30, gender:'girl'},
                                    {name:'Johanna', age:28, gender:'girl'},
                                    {name:'Joy', age:15, gender:'girl'},
                                    {name:'Mary', age:28, gender:'girl'},
                                    {name:'Peter', age:95, gender:'boy'},
                                    {name:'Sebastian', age:50, gender:'boy'},
                                    {name:'Erika', age:27, gender:'girl'},
                                    {name:'Patrick', age:40, gender:'boy'},
                                    {name:'Samantha', age:60, gender:'girl'}
                                    ]">
        I have {{friends.length}} friends. They are:
        <input type="search" ng-model="q" placeholder="Фильтр друзей..." aria-label="Фильтр друзей" />
        <input type="checkbox" ng-model="a" aria-label="Только девушки">Только девушки...
        <ul>
            <li ng-repeat="friend in results = friends | filter:q| myFilter: Run (myRuningFunction):true">
                [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
            </li>
            <li ng-if="results.length == 0">
                <strong>No results found...</strong>
            </li>
        </ul>
        <ul>
            <li ng-repeat="friend in results = friends | filter:q| myFilter2:true">
                [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
            </li>
            <li ng-if="results.length == 0">
                <strong>No results found...</strong>
            </li>
        </ul>

    </div>
</body>
</html>



Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
var app = angular.module('app',[]);

app.filter('myFilter', function () {
    return function (items, runingFunction) {
        // items массив входящих который надо отфильтровать
        // runingFunction функция фильтрующая массив входящих
        if  (runingFunction){  // предполагаем, что runingFunction  это имя функции, которую будем запускать
            var myFunction = runingFunction;
            var arguments2=[];
            if (arguments.length>1) {        //читаем переданные дополнительные аргументы
                for(var i=2;i<arguments.length;i++) {
                    arguments2[arguments2.length]=arguments[i];
                }
            }
            var resultFilter = [];
            for (var item = 0; item < items.length;item++){    //применяем нашу функцию к каждому элементу фильтруемого массива
                arguments2[arguments2.length]=items[item];
                if (myFunction.apply (this,arguments2)==true){        // наша фильтрующая функция должна возвращать true если этот элемент надо оставить
                    resultFilter[resultFilter.length]=items[item];
                }
            }
            return resultFilter;
        }
        return false;
    };
});

app.controller ('appMain', function($scope) {

    $scope.Run = function (functionName) {
        if (typeof functionName == 'function') return functionName;  // проверяем, что arg1 это функция в $scope, если так то вернуть её
        return false;
    }

    $scope.myRuningFunction = function () {
        // в нашей фунции аргументы получаем через arguments , элемент фильтруемого массива всегда будет последним элементом arguments[arguments.length-1]
        var item = arguments[arguments.length - 1];
        for (var i = 0; i < arguments.length - 1; i++) {
            // читаем аргументы переданные в функцию
        }
        //alert('Переменная из $scope = '+$scope.name + ' Переменная переданная в аргументах argument[0]='+arguments[0]);
        return true; //если все хорошо
    }


    $scope.name = 'World';
});

app.filter('myFilter2', function () {
    return function (items, runingFunction) {
        //alert(' Переменная переданная в аргументах ='+runingFunction)
        $scope.name;

        return false;
    };
});



myFilter2 это пример того, что при работе с исходным вариантом scope не виден, и будет ошибка

При работе с myFilter теперь можно передавать любую функцию из scope и передавать в нее любое количество аргументов и эта функция все так же останется в области видимости scope

Для работы надо обязательно использовать вот такую конструкцию myFilter: Run (myRuningFunction):argument1:argument2...:argumentN
Тогда при вызове данного фильтра, техническая функция Run произведет поиск в scope функции myRuningFunction и вернет её обратно в фильтр
После чего в теле фильтра будет вызвана эта функция со всеми переданными аргументами и если функция по результату своей работы вернет true, то этот элемент не исключается.

Как-то так...
...
Рейтинг: 0 / 0
AngularJS нетривиальный фильтр
    #38983648
D0KX
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
не все так просто в нашем королевстве :(
Мой вариант тоже не есть хорошее решение.
Основных минусов два.
Первое, что в данном примере фактически фильт можно применять только в одном месте:

так работает:
Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
    
    <ul>
            <li ng-repeat="friend in results = friends | filter:q| myFilter: Run (myRuningFunction):true">
                [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
            </li>
            <li ng-if="results.length == 0">
                <strong>No results found...</strong>
            </li>
        </ul>



так не работает второй фильтр:
Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
        <ul>
            <li ng-repeat="friend in results = friends | filter:q| myFilter: Run (myRuningFunction):true">
                [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
            </li>
            <li ng-if="results.length == 0">
                <strong>No results found...</strong>
            </li>
        </ul>
        <ul>
            <li ng-repeat="friend in results = friends | filter:q| myFilter: Run (myRuningFunction2):false">
                [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
            </li>
            <li ng-if="results.length == 0">
                <strong>No results found...</strong>
            </li>
        </ul>



так как при вызове фильтра второй раз аргументы будут переданы какие есть в первом :(

Второй минус, это то что данное решение выполняется каждый раз как только что-то меняется в модуле, даже независимое от данного фильтра, так что чтобы не грузить проц надо прописывать проверку, что аргументы в фильтре не изменились.

Так что надо еще допились напильником или выкинуть это решение и искать другое
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / HTML, JavaScript, VBScript, CSS [игнор отключен] [закрыт для гостей] / AngularJS нетривиальный фильтр
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]