1

I made custom directive that use Angular UI typeahead directive inside, but not working as expected. In my directive model is not updating on select. Anybody helps with that ? For testing i used static array instead of http service. Plunker HERE.

.directive('httpDictionary', ['$compile', function($compile){
    return {
        scope: {
        },
        restrict: 'A',
        controllerAs: "dm",
        controller: ['$scope', '$http', 'ARRAY', function($scope, $http, ARRAY){
           var dm = this;
           dm.dict = function(val){
            return ARRAY; // for testing only
            // return $http.get($scope.dictionaryUrl, { ...
           } 
        }],
        link: function(scope, element, attributes, ngModel) {
            scope.dictionaryUrl = attributes.httpDictionary;
            element.removeAttr('http-dictionary'); // avoid loop
            element.attr('uib-typeahead', 'd for d in dm.dict($viewValue)');
            $compile(element)(scope);
        }
    };    
}])
marioosh
  • 27,328
  • 49
  • 143
  • 192

2 Answers2

0

To help with binding to a model, I usually use uib-typeahead setting typeahead-on-select. That way, you can check against or execute some additional code when the new model is set.

I made a plunker off your code found here but made some small tweaks:

  • I isolated the input text field into its own view so as to separate the functionality from the parent view.

  • I passed the test model to the directive's scope attribute and then bound it to the directives controller (using bindToController attribute) so if you ever needed the test model to communicate with the parent controller in the future, you could do so.

Hopes this helps.

Lynchy
  • 183
  • 1
  • 1
  • 9
  • Your code works ok, but directive in that form (`restrict:'E'`) is not usable with other directives. I need that works as attribute. – marioosh Aug 31 '17 at 10:06
0

I made this works like below. Plunker code here. I've bind ngModel in directive scope and used typeahead-on-select callback function. I don't think so this is elegant, but works. I've been thinking about using $watch, but without success. If You have a better soultion, i'll be glad.

.directive('httpDictionary', ['$compile', function($compile){
    return {
        scope: {
          ngModel: '='
        },
        restrict: 'A',
        controllerAs: "dm",
        controller: ['$scope', '$http', 'ARRAY', function($scope, $http, ARRAY){
           var dm = this;
           dm.dict = function(val){
            return ARRAY; // for testing only
            // return $http.get($scope.dictionaryUrl, { ...
           } 
           dm.select = function($model) {
              $scope.ngModel = $model;
           }           
        }],
        link: function(scope, element, attributes, ngModel) {
            scope.dictionaryUrl = attributes.httpDictionary;
            element.removeAttr('http-dictionary'); // avoid loop
            element.attr('uib-typeahead', 'd for d in dm.dict($viewValue)');
            element.attr('typeahead-on-select','dm.select($model)');
            element = $compile(element)(scope);
        }
    };    
}])
marioosh
  • 27,328
  • 49
  • 143
  • 192