gpt4 book ai didi

javascript - AngularJS 指令不触发更改回调

转载 作者:行者123 更新时间:2023-11-28 19:21:45 25 4
gpt4 key购买 nike

我已经创建了一个与 CSS 样式一起使用的数字步进器,但在手动输入时让它触发 ng-change 时遇到问题。

我在 plunker 上创建了一个日志来说明回调何时被触发。正如您通过使用它所看到的,当您单击步进器箭头时它可以正常工作,但当您直接在框中键入时则不行。

当前代码示例: Plunker

HTML:

<div class="stepper-container">
<input type="text" ng-model="ngModel">
<button class="stepper-up fa fa-chevron-up" ng-click="increment()"></button>
<button class="stepper-down fa fa-chevron-down" ng-click="decrement()"></button>
</div>

JavaScript:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
$scope.myModel = null;
$scope.log = [];

$scope.someMethod = function () {
$scope.log.push('Change event on ' + $scope.myModel);
}
});

app.directive('numericStepper', function () {
return {
restrict: 'EA',
require: 'ngModel',
scope: {
ngModel: '='
},
replace: true,
templateUrl: 'numeric-stepper.html',
link: function (scope, element, attrs, ngModelCtrl) {
console.log('NumericStepper::link', ngModelCtrl.$viewValue);

var sizingUnit = null;
var css3Lengths = [
// Percentage
'%',
// Font Relative
'em', 'ex', 'ch', 'rem',
// Viewport Relative
'vw', 'vh', 'vmin', 'vmax',
// Absolute
'cm', 'mm', 'in', 'px', 'pt', 'pc'
];

scope.$watch(function () {
return ngModelCtrl.$modelValue;
}, function (newValue, oldValue) {
updateValue();
});

ngModelCtrl.$formatters.unshift(function (value) {
value = isNaN(parseInt(value)) ? 0 : value;
return value;
});

scope.increment = function () {
updateValue(1)
};

scope.decrement = function () {
updateValue(-1);
};

function updateValue(amount) {
var matches = ngModelCtrl.$viewValue.toString().split(/(-?\d+)/);
var value = (parseInt(matches[1]) || 0) + (amount || 0);
sizingUnit = matches[2].trim();

ngModelCtrl.$setViewValue(value + sizingUnit);
sanityCheck();
}

function sanityCheck() {
var validity = css3Lengths.indexOf(sizingUnit) != -1;
ngModelCtrl.$setValidity('invalidUnits', validity);
}
}

}});

最佳答案

更改模板文本框以包含 ngChange 的隔离范围调用。在该函数中,使用超时允许模型更新/摘要在调用父 Controller 更改函数之前发生...

因此更改您的模板文本框:

<input type="text" ng-model="ngModel" ng-change="textChanged()">

然后更改您的指令:

// $timeout works better here than watch
app.directive('numericStepper', function ($timeout) {

return {
restrict: 'EA',
require: 'ngModel',
scope: {
ngModel: '=',
ngChange: '&' // add me!
},
replace: true,
templateUrl: 'numeric-stepper.html',
link: function (scope, element, attrs, ngModelCtrl) {
console.log('NumericStepper::link', ngModelCtrl.$viewValue);

var sizingUnit = null;
var css3Lengths = [
// Percentage
'%',
// Font Relative
'em', 'ex', 'ch', 'rem',
// Viewport Relative
'vw', 'vh', 'vmin', 'vmax',
// Absolute
'cm', 'mm', 'in', 'px', 'pt', 'pc'
];
/********** DONT NEED THIS
// scope.$watch(function () {
// return ngModelCtrl.$modelValue;
// }, function (newValue, oldValue) {
// updateValue();
// });
******************/

// Add this function
scope.textChanged = function() {
$timeout(function(){
updateValue();
scope.ngChange(); }, 500); // could be lower
}
ngModelCtrl.$formatters.unshift(function (value) {
value = isNaN(parseInt(value)) ? 0 : value;
return value;
});

scope.increment = function () {
updateValue(1)
};

scope.decrement = function () {
updateValue(-1);
};

function updateValue(amount) {
var matches = ngModelCtrl.$viewValue.toString().split(/(-?\d+)/);
var value = (parseInt(matches[1]) || 0) + (amount || 0);
sizingUnit = matches[2].trim();

ngModelCtrl.$setViewValue(value + sizingUnit);
sanityCheck();
}

function sanityCheck() {
var validity = css3Lengths.indexOf(sizingUnit) != -1;
ngModelCtrl.$setValidity('invalidUnits', validity);
}
}
}
});

还有一个正在工作的plunker

关于javascript - AngularJS 指令不触发更改回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28734879/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com