//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
在主 Controller 中的searchFilter
var从指令接收新值之前运行。但是,在指令内部登录后,一切都会按预期进行。为什么会这样呢?我的解决方案
在我的简单示例中了解了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>
最佳答案
您在标题中回答了自己的问题!观看'='
而未观看'&'
输入 View 值更改
ng-model
值更改并触发ng-change()
ng-change添加一个$ viewChangeListener,并且被称为同一循环。
看:
ngModel.js#L714和ngChange.js实现。
那时
$scope.searchFilter
尚未更新。 Console.log的旧值searchFilter
通过数据绑定(bind)更新。 更新:仅当POC需要一个额外的周期才能传播该值时,您可以执行以下操作。请参阅其他anwser(@NewDev,以获取更清洁的方法)。
.controller('mainCtrl', function ($scope, $timeout){
$scope.loadResults = function (){
$timeout(function(){
console.log($scope.searchFilter);
});
};
});