2015-07-27 4 views
0

Я нашел половину ответа на мою проблему в принятом ответе на этот пост. How do I filter an array with AngularJS and use a property of the filtered object as the ng-model attribute?Угловая матрица фильтров по определенным значениям свойств

Я задавался вопросом, возможно ли отфильтровать другое поле, которое создало бы массив этих объектов, а затем использовать значения из двух разных объектов в этом массиве.

что-то вроде этого ... (ТД с нг-шоу = "data.Options.HasMap")

<tbody> 
      <tr ng-repeat="row in data.Rows"> 
       <td ng-repeat="col in row.Columns" ng-show="{{col.Visible}}"> 
        {{ col.Value }} 
       </td> 
       <td ng-show="data.Options.HasMap" ng-repeat="hidden in row.Columns | filter:{Visible:false} track by $index"> 
        {{hidden.Value | filter:{HeaderText:'Latitude'}}} , {{hidden.Value | filter:{HeaderText:'Longitude'}}} 
       </td> 
       <td ng-show="data.Options.HasSuppression"> 

       </td> 
       <td ng-show="data.Options.HasAction"> 

       </td> 
      </tr> 
     </tbody> 

мой файл Json имеет массив столбцов, как ...

"Columns": [{ 
       "HeaderText": "R1 - F1", 
       "Value": "data1", 
       "Visible": true 
     },... 

, и я хотел бы вытащить столбцы, где Visible: false, а затем выбрать значения двух разных объектов с конкретными заголовками.

Извините, если это звучит запутанно. любая помощь будет оценена по достоинству. Я очень новичок в Angular и просто пытаюсь понять, что происходит!

Редактировать. Просто чтобы указать, что я могу добраться до одного из объектов столбца, мне это нужно.

  <td ng-show="data.Options.HasMap" ng-repeat="hidden in row.Columns | filter:{HeaderText:'Latitude'} track by $index"> 
       {{ hidden.Value }} 
      </td> 

Но мне действительно нужна как широта и объекты столбцов долготы для создания URL с переменными строками запроса.

я также пробовал ...

<td ng-show="data.Options.HasMap"> 
        {{ row.Columns.Value | filter:{HeaderText:'Latitude'} }} , {{ row.Columns.Value | filter:{HeaderText:'Longitude'} }} 
       </td> 

ответ

0

Эта линия будет принимать значение hidden.Value (что в вашем примере выше "R1 - F1") и применить фильтр { HeaderText: 'Latitude'} к нему:

{{hidden.Value | filter:{HeaderText:'Latitude'}}} , {{hidden.Value | filter:{HeaderText:'Longitude'}}} 

Вы пытаетесь фильтровать строку, используя фильтр, предназначенный для массива объектов; это просто вернет пустой массив и, безусловно, не то, что вы хотите. Из вашего примера не ясно, где определены свойства «Долгота» и «Локатор». Возможно, вам нужно снова отфильтровать список столбцов? Что-то вроде:

Я не совсем уверен, что вы пытаетесь сделать, поясните, где определены свойства Latitude/Longitude.

Еще одна вещь, на которую нужно обратить внимание - это настраиваемые фильтры, это также может помочь. Посмотрите на Using filter to create array, then using that array to filter ng-options

EDIT

Чтобы получить две колонки с HeaderText = "Широта" и HeaderText = "Долгота", вы можете сделать:

<span ng-repeat="col in row.Columns | filter:{HeaderText: "Latitude"}> 

Если Безразлично» в зависимости от ваших потребностей, посмотрите на пользовательские фильтры.Вот пример, который будет фильтровать текст заголовка сопоставления любые значения проходят в:

app.filter('filterByHeaderText', function() { 
    return function(input, headerText) { 
     // Input is the array to be filtered, 
     input = input || []; 
     headerText = headerText || []; 

     var output = []; 
     for (var i = 0; i < input.length; i++) { 
     for (var j = 0; j < headerText.length; j++) { 
      // If input matches any of the headerText, then add it to the list 
      if (input[i].headerText.indexOf(headerText[j].trim()) >= 0) { 
      output.push(input[i]); 
      break; 
      } 
     } 
     } 

     return output; 
    }; 
    }) 

Этот фильтр может быть использован следующим образом:

<span ng-repeat="item in row.Columns | filterByHeaderText: ['Latitude', 'Longitude']"> 
+0

жаль, что я должен отметить, что долготе и широтные свойства - фактически объекты внутри столбцов. Поэтому я хочу вытащить два объекта столбца, один с свойством HeaderText «Latitude» и один с HeaderText «Longitude». - Возможно ли это? – Stuart

0

К сожалению это мой первый ответ здесь. Я сделал собственный фильтр для фильтрации массива, как это. Допустим, у нас есть массив JSON объектов, как это:

var myArray=[{prop1:"val1", prop2:"val2", ...}, ...] 

Параметр поиска определяется в property name : property value пар, которые должны быть структурированы следующим образом:

var examplePairs={ 
     prop1:"val1", 
     prop2:["val2", "val3"], 
     prop4:{eqStart:true, eqEnd:false, iStart:123, iEnd: 321} 
     }; 

Этот пример ищет массив для всех матчей, где недвижимость prop1 имеют значение val1 и свойства prop2 имеют значение val2 или val3 и свойство prop3 от интервала [123,321>

Примечание: для интервального поиска данные внутри объектов в массиве должны быть числом (его не следует определять без кавычек).

В комментариях есть пояснения. Для вашего конкретного фильтра случае вызова, как это:

{{ pairs={HeaderText:['Latitude', 'Longitude'], Visible:true} }} 
<span ng-repeat="col in row.Columns | jsonArrayMultiFilter : pairs > 

Или позвоните фильтр из контроллера, как это:

var pairs={HeaderText:['Latitude', 'Longitude'], Visible:true} 
$scope.row.Columns=$filter('jsonArrayMultiFilter')($scope.row.Columns, pairs); 

Пользовательский код фильтра:

.filter('jsonArrayMultiFilter', function() { 
return function(x, pairs) { 
    //filters 
    //pairs = property:value pairs 
    //in case same properties can have multiple value pairs should be defined as followed 
    // {property:[value1, value2]} 
    //if value of property fits inside interval it should be defined as followed 
    // {property:{eqStart:true, eqEnd:false, iStart:"start of interval", iEnd:"end of interval"}} 
    // if value in data is string it searches if string contains searched value 
    var keys=Object.keys(pairs); 
    //console.log(keys); 
    var newData=[]; 
    var counter, tempCount, expression; 
    for (var i=0;i<x.length;i++){ 
    //iterate data then apply multiple filters 
    //set counter value 0 for each itteration trough data 
    //if all pairs satisfies conditions counter should equal (keys.length - 1) 
    //for effitiency when condition is not satisfied loop should be broken on first fail 
    counter=0; 
    for (var j=0; j < keys.length; j++){ 
     //iterrate through pairs 
     if (pairs[keys[j]].constructor === Array){ 
     //if property has multiple values itterate trough values 
     tempCount=counter; 
     for (var k=0; k < pairs[keys[j]].length; k++){ 
      //create regexp to perform case insensitive search 
      var rExp = new RegExp(pairs[keys[j]][k], "i"); 
      //if value is a string expression searches the string if it is number finds exact match 
      expression=(typeof x[i][keys[j]] == 'string' || x[i][keys[j]] instanceof String)?x[i][keys[j]].search(rExp)>-1:x[i][keys[j]]==pairs[keys[j]][k]; 
      if (expression){ 
      counter++; 
      } 
     } 
     if (tempCount==counter){ 
      //break itteration because one condition isn't satisfied for data x[i] 
      break; 
     } 
     }else{ 
     //if not array but is object and property['iStart'] is not null and not undefined check if value is from interval 
     if(typeof pairs[keys[j]]['iStart'] !== 'undefined' && pairs[keys[j]]['iStart'] !== null){ 
      // if value is from interval 
      var leftLimit=pairs[keys[j]]['eqStart']?x[i][keys[j]] >= pairs[keys[j]]['iStart']:x[i][keys[j]] > pairs[keys[j]]['iStart']; 
      var rightLimit=pairs[keys[j]]['eqEnd']?x[i][keys[j]] <= pairs[keys[j]]['iEnd']:x[i][keys[j]] < pairs[keys[j]]['iEnd']; 
      if (leftLimit && rightLimit){ 
      counter++; 
      } 
      else{ 
      //break itteration because one condition isn't satisfied for data x[i] 
      break; 
      } 
     }else{ 
      //create regexp to perform case insensitive search 
      var rExp = new RegExp(pairs[keys[j]], "i"); 
      //if value is a string expression searches the string if it is number finds exact match 
      expression=(typeof x[i][keys[j]] == 'string' || x[i][keys[j]] instanceof String)?x[i][keys[j]].search(rExp)>-1:x[i][keys[j]]==pairs[keys[j]]; 
      //if property has one value make comparsion 
      if (x[i][keys[j]]==pairs[keys[j]]){ 
      counter++; 
      } 
      else { 
      //break itteration because condition isn't satisfied for data x[i] 
      break; 
      } 
     } 
     } 
     //if all conditions are satisfied 
     if (counter >= keys.length){ 
     newData.push(x[i]); 
     } 
    } 
    } 
    return newData; 
}; 
}) 
Смежные вопросы