ng-change 和 ng-focus 在自定义输入指令中不起作用
ng-change and ng-focus not working in custom input directive
我正在自定义一个包含标签的输入指令。我试了几天,参考了一些文章。
唯一的问题是,除了 ng-change、ng-blur 和 ng-focus,所有其他事件都有效。 https://jsfiddle.net/luneyq/mw3oz2pr/
当然我可以自己手动绑定这三个事件,它们可以作为 https://jsfiddle.net/luneyq/bp7f3z1o/
但我真的不知道为什么 ng-change、ng-blur 和 ng-focus 不起作用。这三个活动有什么特别之处吗?
有人可以帮忙吗?
我的代码如下:
<div ng-app="myApp">
<div ng-controller="MainController">
<my-input type="number" name="valueNumber1" ng-model="obj.valueNumber1" label="Age" ng-click="log('click')" ng-change="log('change')" ng-blur="log('blur')" ng-focus="log('focus')" ng-mouseleave="log('mouseleave')"></my-input>
<div id="result"></div>
</div>
JS:
var app = angular.module("myApp", []);
app.controller('MainController', function($scope, $window){
$scope.obj = {valueNumber1: 10};
$scope.log = function(text) {
document.getElementById("result").innerHTML = text + ':' + $scope.obj.valueNumber1 + "<br>" + document.getElementById("result").innerHTML;
};
});
app.directive('myInput', function() {
return {
require: '^ngModel',
restrict: 'EA',
scope: {
ngModel: '=',
name: '@name',
label: '@label'
},
replace: true,
transclude: true,
priority: 10,
template: '<div>' +
'<label for="{{ name }}">{{label}}</label>' +
'<input id="{{ name }}" ng-model="ngModel" />' +
'</div>',
compile: function(tElement, tAttrs, transclude) {
var tInput = tElement.find('input');
// Move the attributed given to 'custom-input' to the real input field
angular.forEach(tAttrs, function(value, key) {
if (key.charAt(0) == '$')
return;
tInput.attr(key, value);
});
tElement.replaceWith('<div class="cbay-input-div">' + tElement.html() + '</div>');
return;
}
};
});
提前致谢。
问题是 compilation/transclusion/replace 没有按照您认为的方式工作(不确定您在哪里做出了不正确的假设)。
你的代码有什么问题:
1).您使用的属性名称不正确:您应该使用 tInput.attr(tAttrs.$attr[key], value);
而不是 tInput.attr(key, value);
.
2).尽管您对 compile
函数中的 tElement
进行了更改,但在 my-input
中指定的所有指令都会被编译和链接。证明在这里 - https://jsfiddle.net/fyuz3auc/3/,看看 myTest
指令及其在控制台中的输出:尽管你做了任何努力,它仍然应用于 myInput
。
3).您为指令指定了 scope
。因此它有一个独立的范围,因此你在其中编译的任何东西都无法访问 MainController
的 log
函数,这就是你的 log
不工作的原因。这是 fiddle 证明:https://jsfiddle.net/m5tba2mf/1/(看看从 compile
返回的 link
函数中的 $scope.log = $scope.$parent.log
)。
为了解决第二个问题,我建议您尝试替代方法 - 我在我的项目中使用它,并且非常喜欢它。这个想法是将 terminal
与极高优先级和 $compile
结合使用。这是更新后的 fiddle,我认为我在那里所做的非常简单:https://jsfiddle.net/uoat55sj/1/.
我正在自定义一个包含标签的输入指令。我试了几天,参考了一些文章。
唯一的问题是,除了 ng-change、ng-blur 和 ng-focus,所有其他事件都有效。 https://jsfiddle.net/luneyq/mw3oz2pr/
当然我可以自己手动绑定这三个事件,它们可以作为 https://jsfiddle.net/luneyq/bp7f3z1o/
但我真的不知道为什么 ng-change、ng-blur 和 ng-focus 不起作用。这三个活动有什么特别之处吗? 有人可以帮忙吗?
我的代码如下:
<div ng-app="myApp">
<div ng-controller="MainController">
<my-input type="number" name="valueNumber1" ng-model="obj.valueNumber1" label="Age" ng-click="log('click')" ng-change="log('change')" ng-blur="log('blur')" ng-focus="log('focus')" ng-mouseleave="log('mouseleave')"></my-input>
<div id="result"></div>
</div>
JS:
var app = angular.module("myApp", []);
app.controller('MainController', function($scope, $window){
$scope.obj = {valueNumber1: 10};
$scope.log = function(text) {
document.getElementById("result").innerHTML = text + ':' + $scope.obj.valueNumber1 + "<br>" + document.getElementById("result").innerHTML;
};
});
app.directive('myInput', function() {
return {
require: '^ngModel',
restrict: 'EA',
scope: {
ngModel: '=',
name: '@name',
label: '@label'
},
replace: true,
transclude: true,
priority: 10,
template: '<div>' +
'<label for="{{ name }}">{{label}}</label>' +
'<input id="{{ name }}" ng-model="ngModel" />' +
'</div>',
compile: function(tElement, tAttrs, transclude) {
var tInput = tElement.find('input');
// Move the attributed given to 'custom-input' to the real input field
angular.forEach(tAttrs, function(value, key) {
if (key.charAt(0) == '$')
return;
tInput.attr(key, value);
});
tElement.replaceWith('<div class="cbay-input-div">' + tElement.html() + '</div>');
return;
}
};
});
提前致谢。
问题是 compilation/transclusion/replace 没有按照您认为的方式工作(不确定您在哪里做出了不正确的假设)。
你的代码有什么问题:
1).您使用的属性名称不正确:您应该使用 tInput.attr(tAttrs.$attr[key], value);
而不是 tInput.attr(key, value);
.
2).尽管您对 compile
函数中的 tElement
进行了更改,但在 my-input
中指定的所有指令都会被编译和链接。证明在这里 - https://jsfiddle.net/fyuz3auc/3/,看看 myTest
指令及其在控制台中的输出:尽管你做了任何努力,它仍然应用于 myInput
。
3).您为指令指定了 scope
。因此它有一个独立的范围,因此你在其中编译的任何东西都无法访问 MainController
的 log
函数,这就是你的 log
不工作的原因。这是 fiddle 证明:https://jsfiddle.net/m5tba2mf/1/(看看从 compile
返回的 link
函数中的 $scope.log = $scope.$parent.log
)。
为了解决第二个问题,我建议您尝试替代方法 - 我在我的项目中使用它,并且非常喜欢它。这个想法是将 terminal
与极高优先级和 $compile
结合使用。这是更新后的 fiddle,我认为我在那里所做的非常简单:https://jsfiddle.net/uoat55sj/1/.