watchcollection che deglutisce un attributo che viene guardato

Ci sono due attributi selCountry e searchText . C'è un orologio che controlla queste due variables. Il primo è associato ad un elemento selezionato, altrimenti è un field di text di input.

Il comportmento che prevedo è: se cambio il valore a discesa, la casella di text dovrebbe eliminare e viceversa. Tuttavia, a causa del modo in cui ho scritto l'orologio, la prima pressione chiave (post interagire con l'elemento selezionato) inghiotta la pressione del tasto.

Dovrebbe esserci un modo angular di dire angular per non elaborare le variazioni variables che accadono a quelle variables; ancora permettono che i loro cambiamenti si propagino alla vista …?

  $scope.$watchCollection('[selCountry, searchText]', function(newValues, oldValues, scope){ console.log(newValues, oldValues, scope.selCountry, scope.searchText); var newVal; if(newValues[0] !== oldValues[0]) { console.log('1'); newVal = newValues[0]; scope.searchText = ''; } else if(newValues[1] !== oldValues[1]) { console.log('2'); newVal = newValues[1]; scope.selCountry = ''; } $scope.search = newVal; var count = 0; if(records) records.forEach(function(o){ if(o.Country.toLowerCase().indexOf(newVal.toLowerCase())) count++; }); $scope.matches = count; }); 

buttarsi

    Penso che il problema che incontri è che catturi un evento di orologio correttamente, ma quando cambia il valore della seconda variabile, viene anche catturato dal gestore di watchCollection e ne cancella anche quel valore. Per esempio:

     selCountry = 'Mexico' 

    Si cambia poi

     selText = 'City' 

    Il codice cattura la modifica di selText come ci si aspetterebbe. Continua a svuotare selCountry. Ma dal momento che si modifica il valore di selCountry sull'object scope, ciò fa anche ricall watchCollection che poi dice "va bene adesso cancellare searchText".

    Devi essere in grado di risolvere questo problema catturando le modifiche utilizzando i gestori di events onChange utilizzando la direttiva sui cambiamenti. Provare quanto segue

     // Comment out/remove current watchCollection handler. // Add the following in JS file $scope.searchTextChange = function(){ $scope.selCountry = ''; $scope.search = $scope.searchText; search($scope.search); }; $scope.selectCountryChange = function(){ $scope.searchText = ''; $scope.search = $scope.selCountry; search($scope.search); }; function search(value){ var count = 0; if(records) records.forEach(function(o){ if(o.Country.toLowerCase().indexOf(value.toLowerCase())) count++; }); $scope.matches = count; } 

    E nel tuo file HTML

     <!-- Add ng-change to each element as I have below --> <select ng-options="country for country in countries" ng-model="selCountry" ng-change="selectCountryChange()"> <option value="">--select--</option> </select> <input type="text" ng-model="searchText" ng-change="searchTextChange()"/> 

    Nuovo plunker: http://plnkr.co/edit/xCWxSM3RxsfZiQBY76L6?p=preview

    Penso che lo stia spingendo troppo, per così dire. Faresti bene con less complessità e watches .

    Ti suggerisco di utilizzare una libreria di terze parti come lodash che rende più semplice la manipolazione di arrays / oggetti. Provi questo plunker http://plnkr.co/edit/YcYh8M , penso che fa quello che stai cercando.

    Deselezionerà il search text each volta che viene selezionata l'elemento country ma filtra automaticamente le options per corrispondere al text di ricerca quando viene digitato qualcosa.

    Modello HTML

     <div ng-controller="MainCtrl"> <select ng-options="country for country in countries" ng-model="selected" ng-change="search = null; searched();"> <option value="">--select--</option> </select> <input type="text" placeholder="search here" ng-model="search" ng-change="selected = null; searched();"> <br> <p> searched: {{ search || 'null' }}, matches : {{ search ? countries.length : 'null' }} </p> </div> 

    JavaScript

     angular.module('myapp',[]) .controller('MainCtrl', function($scope, $http) { $http.get('http://www.w3schools.com/angular/customers.php').then(function(response){ $scope.allCountries = _.uniq(_.pluck(_.sortBy(response.data.records, 'Country'), 'Country')); $scope.countries = $scope.allCountries; }); $scope.searched = function() { $scope.countries = $scope.allCountries; if ($scope.search) { var result = _.filter($scope.countries, function(country) { return country.toLowerCase().indexOf($scope.search.toLowerCase()) != -1; }); $scope.countries = result; } }; });