Rob*_*opp 8 angularjs angularjs-ng-change isolate-scope
//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>
Run Code Online (Sandbox Code Playgroud)
这是一个简化的指令来说明.当我输入到输入,我预计console.log在loadResults注销正是我已经输入.它实际上记录了一个字符,因为loadResults它正好在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>
Run Code Online (Sandbox Code Playgroud)
New*_*Dev 11
究其原因,行为,正确的另一种回答指出,是因为双向绑定一直没有机会改变外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: '<input ng-model="innerModel" ng-change="onChange()">',
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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,ng-change只是自动工作,所以支持的其他指令ngModel,如ng-required.
你在标题中回答了你自己的问题!'='被观看而'&'未被观看
某处外部角度:
输入视图值更改
下一个消化周期:
ng-model价值变化和火灾ng-change()
ng-change 添加了一个 $viewChangeListener 并被称为同一个循环。请参阅: ngModel.js#L714和ngChange.js实现。
那时候$scope.searchFilter还没有更新。Console.log 的旧值
searchFilter通过数据绑定更新。更新:仅作为需要 1 个额外周期来传播值的 POC,您可以执行以下操作。请参阅其他答案(@NewDev 以获得更清晰的方法)。
.controller('mainCtrl', function ($scope, $timeout){
$scope.loadResults = function (){
$timeout(function(){
console.log($scope.searchFilter);
});
};
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7374 次 |
| 最近记录: |