Причина поведения, как справедливо указано в другом ответе, состоит в том, что двусторонняя привязка не имела возможности изменить внешний searchFilter
к моменту времени searchChange()
и, следовательно, loadResults()
был вызван.
Решение, однако, очень хакерское по двум причинам.
Один, вызывающий (пользователь директивы), не должен знать об этих обходных решениях с помощью $timeout
. Если ничего другого, $timeout
должно было быть сделано в директиве, а не в контроллере View.
И два - ошибка, также сделанная OP - заключается в том, что использование ng-model
происходит с другими " ожидания "пользователями таких директив. Если ng-model
означает, что рядом с ним могут использоваться другие директивы, такие как валидаторы, парсеры, форматирующие элементы и слушатели смены вида (например, ng-change
). Чтобы поддерживать его правильно, нужно require: "ngModel"
, а не привязываться к его выражению через scope: {}
. В противном случае все будет работать не так, как ожидалось.
Вот как это делается - для другого примера см. официальную документацию для создания пользовательского элемента управления вводом.
scope: true, // could also be {}, but I would avoid scope: false here
template: '',
require: "ngModel",
link: function(scope, element, attrs, ctrls){
var ngModel = ctrls; // ngModelController
// from model -> view
ngModel.$render = function(){
scope.innerModel = ngModel.$viewValue;
}
// from view -> model
scope.onChange = function(){
ngModel.$setViewValue(scope.innerModel);
}
}
Затем ng-change
просто работает автоматически, а также другие директивы, которые поддерживают ngModel
, например ng-required
.