//main controller
angular.module('myApp')
.controller('mainCtrl', function ($scope){
$scope.loadResults = function (){
console.log($scope.searchFilter);
};
});
// directive
angular.module('myApp')
.directive('customSearch', function () {
return {
scope: {
searchModel: '=ngModel',
searchChange: '&ngChange',
},
require: 'ngModel',
template: '<input type="text" ng-model="searchModel" ng-change="searchChange()"/>',
restrict: 'E'
};
});
// html
<custom-search ng-model="searchFilter" ng-change="loadResults()"></custom-search>
这是一个简化的指令来说明。当我输入输入时,我希望输入console.log
完全loadResults
注销我已经输入的内容。它实际上记录了一个字符,因为它正在主控制器中loadResults
的 var 接收来自指令的新值之前运行。searchFilter
然而,在指令中登录,一切都按预期工作。为什么会这样?
我的解决方案
在我的简单示例中了解了 ngChange 发生的情况后,我意识到我的实际问题更加复杂,因为我实际传入的 ngModel 是一个对象,我正在更改其属性,而且我我正在使用带有此指令的表单验证作为输入之一。我发现在指令中使用 $timeout 和 $eval 解决了我所有的问题:
//main controller
angular.module('myApp')
.controller('mainCtrl', function ($scope){
$scope.loadResults = function (){
console.log($scope.searchFilter);
};
});
// directive
angular.module('myApp')
.directive('customSearch', function ($timeout) {
return {
scope: {
searchModel: '=ngModel'
},
require: 'ngModel',
template: '<input type="text" ng-model="searchModel.subProp" ng-change="valueChange()"/>',
restrict: 'E',
link: function ($scope, $element, $attrs, ngModel)
{
$scope.valueChange = function()
{
$timeout(function()
{
if ($attrs.ngChange) $scope.$parent.$eval($attrs.ngChange);
}, 0);
};
}
};
});
// html
<custom-search ng-model="searchFilter" ng-change="loadResults()"></custom-search>