2012-10-18 24 views
19

sto usando AjgularJS sulla mia pagina e voglio aggiungere un campo per usare il completamento automatico da jqueryui e il completamento automatico non attiva la chiamata ajax.Problemi con jQuery autocomplete + AngularJS

ho testato lo script su una pagina senza angolare (ng-app e ng-controller) e funziona bene, ma quando metto lo script su una pagina con angularjs smette di funzionare.

qualche idea? sceneggiatura

jquery:

$(function() { 

    $('#txtProduct').autocomplete({ 
     source: function (request, response) { 

      alert(request.term); 

     }, 
     minLength: 3, 
     select: function (event, ui) { 

     } 
    }); 

}); 
  • interessante nota: quando chiamo lo script su Chrome ispettore del completamento automatico inizia a lavorare !!!
  • Versioni: AngularJS: 1.0.2 - jQueryUI: 1.9.0

CONCLUSIONE: Il completamento automatico widget dal jQueryUI deve essere inizializza dall'interno di una direttiva personalizzato di AngularJS come l'esempio:

Markup

<div ng-app="TestApp"> 
    <h2>index</h2> 
    <div ng-controller="TestCtrl"> 

     <input type="text" auto-complete>ddd</input> 

    </div> 
</div> 

sceneggiatura angolare

<script type="text/javascript"> 

    var app = angular.module('TestApp', []); 

    function TestCtrl($scope) { } 

    app.directive('autoComplete', function() { 
     return function postLink(scope, iElement, iAttrs) { 

      $(function() { 
       $(iElement).autocomplete({ 
        source: function (req, resp) { 
         alert(req.term); 
        } 
       }); 
      }); 

     } 
    }); 

</script> 
+0

si dovrebbe cercare di caricarli nel $ (document) .ready(); Controlla anche gli errori nella console di Firebug. –

+0

Concordato: è necessario verificare i conflitti tra AngularJS e JQuery. Non sembra esserci nessuno in un semplice test: http: // jsfiddle.net/mccannf/w69Wt/ – mccannf

+1

Potrebbe non essere rilevante dal problema che si sta vedendo, ma penso che dovresti usare jquery all'interno della direttiva personalizzata (funzione link). – Tosh

risposta

35

Forse solo bisogno di farlo in un "modo angolare" ... cioè, per usare una direttiva per impostare gli elementi DOM e fare binding di eventi, utilizzare un servizio per ottenere i dati, e utilizzare un controller per fare la logica di business ... il tutto mentre sfruttando la bontà iniezione di dipendenza che è angolare ...

un servizio per ottenere i dati di completamento automatico ...

app.factory('autoCompleteDataService', [function() { 
    return { 
     getSource: function() { 
      //this is where you'd set up your source... could be an external source, I suppose. 'something.php' 
      return ['apples', 'oranges', 'bananas']; 
     } 
    } 
}]); 

una direttiva per fare il lavoro di impostare il plugin di completamento automatico.

app.directive('autoComplete', function(autoCompleteDataService) { 
    return { 
     restrict: 'A', 
     link: function(scope, elem, attr, ctrl) { 
        // elem is a jquery lite object if jquery is not present, 
        // but with jquery and jquery ui, it will be a full jquery object. 
      elem.autocomplete({ 
       source: autoCompleteDataService.getSource(), //from your service 
       minLength: 2 
      }); 
     } 
    }; 
}); 

E di utilizzare con la marcatura ... Avviso il modello ng per impostare un valore sul $ portata con ciò che si seleziona.

Queste sono solo le basi, ma speriamo che questo aiuti.

+0

L'elem.autocomplete deve essere $ (elem) .autocomplete –

+3

@AshMcConnell: se jQuery è registrato sulla pagina prima di Angular, l'argomento elem della funzione di collegamento è già un oggetto jQuery. Quindi non è richiesto $(). ;) Angolare è liscia come quella. –

+0

grazie! Non lo sapevo, controllerò l'ordine di importazione quando torno al lavoro domani! (È solo l'ordine delle importazioni che intendi?) –

14

Ho dovuto fare un po 'più di lavoro per farlo funzionare utilizzando un servizio $ http.

Il servizio:

app.factory("AutoCompleteService", ["$http", function ($http) { 
    return { 
     search: function (term) { 
      return $http.get("http://YourServiceUrl.com/" + term).then(function (response) { 
       return response.data; 
      }); 
     } 
    }; 
}]); 

La direttiva:

app.directive("autocomplete", ["AutoCompleteService", function (AutoCompleteService) { 
    return { 
     restrict: "A", 
     link: function (scope, elem, attr, ctrl) { 
      elem.autocomplete({ 
       source: function (searchTerm, response) { 
        AutoCompleteService.search(searchTerm.term).then(function (autocompleteResults) { 
         response($.map(autocompleteResults, function (autocompleteResult) { 
          return { 
           label: autocompleteResult.YourDisplayProperty, 
           value: autocompleteResult 
          } 
         })) 
        }); 
       }, 
       minLength: 3, 
       select: function (event, selectedItem) { 
        // Do something with the selected item, e.g. 
        scope.yourObject= selectedItem.item.value; 
        scope.$apply(); 
        event.preventDefault(); 
       } 
      }); 
     } 
    }; 
}]); 

il codice HTML:

<input ng-model="YourObject" autocomplete /> 
+0

Ricevo l'errore seguente 'Errore: autocompleteResult non è definito' – sar

+0

Il tuo servizio restituisce qualsiasi informazione? Ad esempio, nel mio servizio sto restituendo response.data. Se si restituisce anche questo, assicurarsi che la chiamata di servizio restituisca anche i dati. – Jason

+0

@Jason: puoi mostrarmi il formato per i dati di ritorno di json dal metodo get. –

Problemi correlati