javascript AngularJS:在编写韩文字符时触发 ng-change、ng-keyup 或 $scope.$watch
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27663149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS: trigger ng-change, ng-keyup or $scope.$watch while composing Korean characters
提问by migu
I'm building a Korean vocabulary trainer and I want to compare user input as people type.
我正在构建一个韩语词汇训练器,我想将用户输入与人们输入的内容进行比较。
In Korean and some other Asian languages, you compose letters with multiple keyup events. In Chrome, $scope.$watch, ng-keyup and ng-change only get triggered after the letter has been fully composed and either a new letter or a space has been entered. I don't mind AngularJS not triggering anything until the last letter has been fully composed but once the letter has been completed, it should trigger without having to add a whitespace or starting the next word.
在韩语和其他一些亚洲语言中,您可以使用多个键盘事件来编写字母。在 Chrome 中,$scope.$watch、ng-keyup 和 ng-change 仅在字母完全组合并输入新字母或空格后才会触发。我不介意 AngularJS 在最后一个字母完全写好之前不会触发任何东西,但是一旦字母完成,它应该触发而不必添加空格或开始下一个单词。
HTML:
HTML:
<form name="forms.vocabularyForm">
<input name="answer" id="answer" ng-model="vocabularyCtrl.answer" ng-change="vocabularyCtrl.checkChange()" ng-keyup="vocabularyCtrl.checkKeyUp($event)" type="text" />
</form>
Controller:
控制器:
.controller('VocabularyCtrl', [
'$scope',
'$location',
function($scope, $location) {
this.checkChange = function () {
console.log("answer change: " + this.answer);
};
this.checkKeyUp = function ($event) {
console.log("answer keyUp: " + this.answer);
};
$scope.$watch('vocabularyCtrl.answer', function (answerNew, answerOld) {
console.log('answerOld: ' + answerOld + ', answerNew: ' + answerNew);
}, true);
};
]);
Example:
例子:
Input: ?
Console:
answerOld: , answerNew:
answer keyUp:
Input: ?
Console:
answerOld: , answerNew:
answer keyUp:
Input: ? (character is now fully composed)
Console:
answerOld: , answerNew:
answer keyUp:
Input: ?? (starting the next character, same behaviour with space bar)
Console:
answerOld: ?, answerNew:
answer change: ?
answer keyUp: ?
采纳答案by migu
As explained by a helpful member of the Angular team, all triggers are intentionally suppressed while composing characters. More details here.
正如 Angular 团队的一位乐于助人的成员所解释的那样,在编写角色时所有触发器都被有意抑制。更多细节在这里。
As suggested, I created a custom directive that manually updates the model while composing characters:
按照建议,我创建了一个自定义指令,用于在组合字符时手动更新模型:
Directive:
指示:
(function() {
'use strict';
angular.module('myApp', [])
// Angular's ng-change, ng-keyup and $scope.$watch don't get triggered
// while composing (e.g. when writing Korean syllables).
// See: https://github.com/angular/angular.js/issues/10588
// This custom directive uses element.on('input') instead, which gets
// triggered while composing.
.directive('cstInput', function() {
return {
restrict: 'A',
require: '^ngModel',
scope: {
ngModel: '=', // sync model
},
link: function (scope, element, attrs, ngModel) {
element.on('input', function() {
scope.ngModel = element.val();
});
}
};
});
})();
Controller: (as suggested by ippi)
控制器:(根据 ippi 的建议)
$scope.$watch('quizzesCtrl.answer', function (answer) {
console.log(answer);
});
HTML:
HTML:
<form ng-controller="QuizzesController as quizzesCtrl">
<input cst-input name="answer" id="answer" ng-model="quizzesCtrl.answer" type="text" />
</form>
Update
更新
I had to change the code to the following to make it work in FireFox (Chrome & Safari work fine with the code above).
我必须将代码更改为以下代码才能使其在 FireFox 中工作(Chrome 和 Safari 与上面的代码一起工作正常)。
Directive:
指示:
(function() {
'use strict';
angular.module('myApp', [])
// Angular's ng-change, ng-keyup and $scope.$watch don't get triggered
// while composing (e.g. when writing Korean syllables).
// See: https://github.com/angular/angular.js/issues/10588
// This custom directive uses element.on('input') instead, which gets
// triggered while composing.
.directive('cstInput', function() {
return {
restrict: 'A',
require: '^ngModel',
link: function (scope, element, attrs, ngModel) {
element.on('input', function() {
scope.$apply(function(){
scope.ngModel = element.val();
scope.$eval(attrs.cstInput, {'answer': scope.ngModel}); // only works if no scope has been defined in directive
});
});
}
};
});
})();
Controller:
控制器:
this.checkAnswer = function (answer) {
if (answer === this.quiz.answer) {
this.isCorrect = true;
}
};
HTML (note that any passed in argument needs to be listed in cst-input-callback):
HTML(请注意,任何传入的参数都需要在 cst-input-callback 中列出):
<form ng-controller="QuizzesController as quizzesCtrl">
<input cst-input="quizzesCtrl.checkAnswer(answer)" ng-model="quizzesCtrl.answer" name="answer" id="answer" type="text" />
</form>
回答by Keith Lee
I found this error in Angular.js 1.2.27, I tried other versions but i coulnd't get any problem. But I found a solution and this will solve your problem.
我在 Angular.js 1.2.27 中发现了这个错误,我尝试了其他版本但我找不到任何问题。但我找到了一个解决方案,这将解决您的问题。
Take a look at this solution https://github.com/mbenford/ngTagsInput/issues/303
看看这个解决方案 https://github.com/mbenford/ngTagsInput/issues/303
angular.module('angularApp')
.directive('ignoreCompositionEvent', function () {
return {
restrict: 'A',
link: function postLink(scope, element) {
//element.val('this is the ignoreCompositionEvent directive');
element.off('compositionstart').off('compositionend');
}
};
});
This is an example. Just open your console and type ?? in Input.
这是一个例子。只需打开您的控制台并输入 ?? 在输入中。
回答by ippi
Using a $watch
you'll be able to catch all updates to the model:
使用 a$watch
您将能够捕获模型的所有更新:
Working example (jsfiddle):
工作示例(jsfiddle):
HTML:
HTML:
<div ng-app ng-controller="myctrl">
<input type="text" ng-model="answer" />
</div>
JS:
JS:
function myctrl($scope) {
$scope.$watch('answer',function(oldVal,newVal){
console.log(oldVal,newVal);
});
}
And for reference, it looks like it could be possible to use ng-model-optionsand assign a compositionupdate
-event to updateOn
. I had no luck with it and resorted to a $watch instead.
作为参考,看起来可以使用ng-model-options并将compositionupdate
-event分配给updateOn
. 我没有运气,而是求助于 $watch 。