我想构建具有与普通输入字段相同的ng-change语法的自定义指令。让我们说我有这样的指示:
;(function() {
'use strict';
angular.module('myMod', []);
angular.module('myMod').directive('myDir', myDirDirective);
function myDirDirective() {
return {
restrict: 'E',
template: '
<input ng-change="checkInput1()" type=...>
<input ng-change="checkInput2()" type=...>
',
controllerAs: 'myDirDirective',
controller: myDirController,
require: 'ngModel',
scope: {},
bindToController: {
model: '='
}
};
}
// Controller goes here...
})(); // EOF
现在我想定义输入检查方法,如
function checkInput1() {
...
if( <changes in input 1 are legit> ) {
fireOuterNgChange();
}
}
function checkInput2() {
...
if( <changes in input 2 are legit> ) {
fireOuterNgChange();
}
}
最后我希望能够使用我的自定义指令,如:
<myDir ng-change="doSomethingAfterSomethingChanged()">
...
</myDir>
一个简单的用例是一个时间选择器,它有几个小时的输入字段:分钟:秒:毫秒。举个例子。我尝试了不同的方法而没有成功我怎么能这样做?
答案 0 :(得分:2)
所以在这里你需要做两件事:
<input>
元素的更改。<my-dir>
的父级。对于(1),你只需按照你的说法做:你在你的指令范围内注册回调(scope.checkInput1 = function() { ... }
)。
然后,要将事件转发给父级(最后模仿<input ng-change>
行为),您需要在Directive的隔离范围中声明一个表达式绑定,如下所示:
scope: {
onDateChange: '&'
}
在父控制器上,假设您在范围中声明了一些$scope.onDirectiveDateChange = function() { ... }
,您只需将回调传递到您的自定义指令中,如下所示:
<my-dir on-date-change="onDirectiveDateChange()"></my-dir>
然后你从你的指令checkInput2
:
scope.onDateChange(); // This will call parent's "onDirectiveDateChange()" if defined
答案 1 :(得分:2)
@Neozaru答案很完美。但为了完整起见,我发布了一个完整的代码示例,以便于理解。在John Papa's Style Guide之后使用controllerAs
语法而不是$scope
(示例用例:具有可重复使用的用户表单):
使用自定义ng-change事件实现自定义指令
首先是模板
// my-dir-template.html
Username: <input type="text" name="username" ng-change="passwordForm.changeHandler()" ng-model="passwordForm.model">
Password: <input type="text" name="password" ng-change="passwordForm.changeHandler()" ng-model="passwordForm.model">
指令和控制器
;(function() {
'use strict';
angular.module('myMod', []);
angular.module('myMod').directive('passwordForm', passwordFormDirective);
function passwordFormDirective() {
return {
restrict: 'E',
templateUrl: 'password-form.html',
controllerAs: 'passwordForm',
controller: passwordFormController,
require: 'ngModel',
scope: {},
bindToController: {
model: '=',
ngChange: '&' // << bind ng-change to controller (not scope)
}
};
}
function passwordFormController() { // no scope injected
// Pseudo this
var vm = this;
// implement controller
vm.changeHandler = changeHandler ;
// // // Method implementations
...
function changeHandler() {
// we could do validation here, altough I'm not sure if this would be a good idea here.
// for now, we only do the change listener notification
if(vm.ngChange === 'function') {
vm.ngChange();
}
}
}
})(); // EOF
现在我们可以将我们的指令与普通的ng-change侦听器一起使用。也许是为了注册新用户:
<password-form ng-model="the-model" ng-change="checkIfUsernameExists()">