1

PlunkrZwei-Wege in AngularJS nicht verbindlich arbeiten sofort Während Benutzerdefinierte Richtlinien Mit

Ich habe eine einfache auto-complete Dropdown. Es funktioniert gut, wenn ich nur Controller verwende.

Ich möchte es wiederverwendbar machen, also habe ich eine benutzerdefinierte Direktive mit isolierten Bereich gemacht.

Aber das Problem ist, wenn ich auf der Suche Text eingeben, ruft es nicht die Controller-Funktion, die ng-change sofort zugewiesen ist. Wenn ich noch einmal tippe, ruft es die Funktion auf. Wiederum nimmt es den Wert, den ich vorher eingegeben habe, nicht den aktuellen Modellwert.

Ich bin neu bei benutzerdefinierten Richtlinien ... Ich weiß wirklich nicht , wie Sie das Modell sofort aktualisieren und vom Direktivenbereich zum Controller-Bereich übergehen.

Andere denken, Ich kann nicht den Funktionsparameter von HTML zu Controller-Funktion übergeben.

Ich denke, ich muss $apply oder $digest irgendwo verwenden .. Aber wo und wie soll ich verwenden?

autofillApp.directive('autofillDropdown', function($rootScope) { 

    return { 

     restrict: 'A', 
     templateUrl: "dropdowntemplate.html", 
     replace: true, 
     scope: { 
      'items': '=autofillItems', 
      'selected': '=autofillSelected', 
      'change': '&autofillChange', 
      'focused': '=autofillFocus', 
      'onSelect': '&autofillOnselect' 
     }, 
     link: function(scope, element, attr) { 
      //console.log(scope.$$watchers); 
      //console.log(element); 
      //console.log(attr); 
      return 
     }, 
     compile: function(element, attributes) { 

      var linkFunction = function($scope, element, attributes) { 
       $scope.$apply(); 
      } 
      return linkFunction; 
     } 

    }; 
}) 

Hier ist mein Plunkr: Plunkr

Antwort

1

Hey Ich habe Ihren Ansatz und fixiert Ihr Problem.

Ihre "change" -Funktion wird mit dem "ng-change" des Eingabefeldes aufgerufen. Das ist okay, richtig. Aber das ng-Modell wird in diesem Moment nicht aktualisiert. Stellen Sie daher nur einen Parameter mit dem Wert der Eingabe bereit.

ng-change="change({searchText:selected})" 

Sie benötigen ein JSON-Objekt mit den rechten Eigenschaftsnamen zur Verfügung zu stellen. In diesem Fall sind wir Weg aus dem isolierten Rahmen so müssen wir es auf diese Weise (mit demselben Eigenschaftsnamen „search“) nennen:

change="SearchCurrencyOnSearchTextChange(searchText)" 

So ist die letzte „change“ Funktion sollte wie folgt aussehen:

$scope.SearchCurrencyOnSearchTextChange = function (searchText) { 
    if (searchText === null || searchText === '' ||searchText ===undefined) { 
     $scope.IsFocused = false; 
    } 
    else { 
     $scope.IsFocused = true; 
     $scope.searchCurrencies = $scope.GetFilteredData(searchText); 
    } 
}; 

Ich habe auch einige Ihrer css ausblenden und zeigen Ansätze entfernt. Wenn Sie ng-show und jquery verwenden, um Dinge anzuzeigen/zu verbergen, wird es Ihnen bald in den Sinn kommen. Versuchen Sie, bei einem zu bleiben.

Auch änderte ich Ihre Richtlinie von „Attribute“ auf „Element“ Richtlinie; D

https://plnkr.co/edit/8sNVFLGOfEcjeLw58Wb6?p=preview

+0

funktioniert gut.Vielen Dank für die Bereitstellung der vollständigen Lösung. –

1

Ich habe versucht, die Vorlage und die Steuerung in der Richtlinie zu bewegen, so dass Sie sie wiederverwenden können. Ich habe einen Controller-Alias ​​für das ViewModel erstellt, das der Eigenschaft controllerAs zugewiesen ist. Hoffentlich in die richtige Richtung Sie hilft:

// Main App 
var app = angular.module("app", ['autofillApp']); 

app.controller("appCtrl", function ($scope, $http) { 
    // Main app controller. 
}); 


//Directive App......................... 
var autofillApp = angular.module('autofillApp', []); 

autofillApp.directive('autofillDropdown',function(){ 


    var AutoFillCtrl = function() { 

     var vm = this; 

     // Get autofill data for country... 
    vm.SearchCurrencyOnSearchTextChange = function() { 
     if (vm.searchTextCurrency === null || vm.searchTextCurrency === '' || vm.searchTextCurrency ===undefined) { 
      vm.IsFocused = false; 
      document.getElementById('currencySearchList').style.display = "none"; 
     } 
     else { 
      vm.IsFocused = true; 
      document.getElementById('currencySearchList').style.display = "block"; 

      vm.SearchCurrencies = vm.GetFilteredData(vm.searchTextCurrency); 
     } 
    }; 

    //Get autofill Result on search for Currency 
    vm.AutoFillCurrency = function (currency) { 
     vm.IsFocused = false; 
     document.getElementById('currencySearchList').style.display = "none"; 
     vm.searchTextCurrency = currency.Name; 
    }; 

    vm.data = [ 

     { 
      Id: 1, 
      Name:"Dollar" 
     }, 
     { 
      Id: 2, 
      Name: "Pound" 
     }, 
     { 
      Id: 3, 
      Name: "Rupee" 
     }, 
     { 
      Id: 4, 
      Name: "Yan" 
     }, 

    ]; 

    vm.GetFilteredData = function (name) { 
     var filteredItems = []; 
     name = name.toLowerCase(); 
     for (var i = 0; i < vm.data.length; i++) { 
      var result = vm.data[i].Name.toLowerCase().search(name); 
      if (result != -1) { 
       filteredItems.push(vm.data[i]); 
      } 
     } 

     return filteredItems; 
    }; 

    }; 

    AutoFillTmpl = '<div class="pos_Rel"><input placeholder="Search Currency e.g. dollar,pound,rupee" type="text" ng-change="vm.change()" ng-model="selected" class="form-control width_full" /><ul ng-show="focused && items" id="currencySearchList"><li class="autofill" ng-repeat="result in vm.items" ng-click="vm.onSelect(result)" ng-bind="result.Name"></li></ul></div>'; 

    return { 

    restrict:'A', 
    controller: AutoFillCtrl, 
    controllerAs: 'vm', 
    bindToController: true, 
    template: AutoFillTmpl, 
    scope: { 
     'items': '=autofillItems', 
     'selected': '=autofillSelected', 
     'change': '&autofillChange', 
     'focused': '=autofillFocus', 
     'onSelect': '&autofillOnselect' 
    } 
}; 

}); 
1

Hier ist JSFiddle arbeiten, müssen Uhr Dienst hinzuzufügen ..

controller: function($scope){ 
     $scope.$watch("selected", function(newVal, oldVal){ 
     $scope.change(); 
     }) 
    } 
+0

ya. Es funktioniert ..thanks.Ich akzeptiere walki12 's Antwort als eine genehmigte Antwort, weil er auch die Lösung für das Übergeben von Parametern aus der Funktion ...... zur Verfügung gestellt hat :) –