如何在测试中更新 angularjs 组件 属性 绑定到 element.val 的输入集
How to update angularjs component property binded to input set with element.val in test
我已经实现了 foo 组件,其模板有一个输入(绑定到 fooValue 属性)当输入具有焦点时按下 "enter" 键时调用该组件控制器函数 onEnter 的属性。
我遇到的问题是,在输入中插入一个值(即 "foo3")并按下 "enter" 键后,fooValue 是不更新输入值。
这是片段:
var app = angular.module('app', []);
app.component('foo', {
template: '<input ng-model="$ctrl.fooValue" enter-key="$ctrl.onEnter()" />',
controller: function() {
this.onEnter = function() {
// this.fooValue is not updated with input value
};
},
bindings: {
fooValue: '@'
}
});
app.directive('enterKey', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind("keydown keypress", function(event) {
var keyCode = event.which || event.keyCode;
// If enter key is pressed
if (keyCode === 13) {
scope.$apply(function() {
// Evaluate the expression
scope.$eval(attrs.enterKey);
});
}
});
}
};
});
describe('test', function() {
describe('foo', function() {
beforeEach(module('app'));
var element,
inputElem;
beforeEach(inject(function($compile, $rootScope) {
var fooScope = $rootScope.$new();
element = angular.element('<foo foo-value="foo1"></foo>');
element = $compile(element)(fooScope);
fooScope.$digest();
}));
it('should set fooValue with foo3', function() {
var controller = element.controller('foo');
inputElem = element.find('input');
inputElem.val('foo3');
inputElem.triggerHandler({
type: 'keydown',
which: 13
});
expect(controller.fooValue).toBe('foo3');
});
});
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.css" />
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine-html.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="https://code.angularjs.org/1.6.1/angular-mocks.js"></script>
</head>
<body>
</body>
</html>
更新 fooValue 缺少什么?
要更新 fooValue,需要触发 input
事件。如果需要 IE11 支持,请使用 change
事件。
以下片段显示它正在工作:
var app = angular.module('app', []);
app.component('foo', {
template: '<input ng-model="$ctrl.fooValue" enter-key="$ctrl.onEnter()" />',
controller: function() {
this.onEnter = function() {
// this.fooValue is now updated with input value
};
},
bindings: {
fooValue: '@'
}
});
app.directive('enterKey', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind("keydown keypress", function(event) {
var keyCode = event.which || event.keyCode;
// If enter key is pressed
if (keyCode === 13) {
scope.$apply(function() {
// Evaluate the expression
scope.$eval(attrs.enterKey);
});
}
});
}
};
});
describe('test', function() {
describe('foo', function() {
beforeEach(module('app'));
var element,
inputElem;
beforeEach(inject(function($compile, $rootScope) {
var fooScope = $rootScope.$new();
element = angular.element('<foo foo-value="foo1"></foo>');
element = $compile(element)(fooScope);
fooScope.$digest();
}));
it('should set fooValue with foo3', function() {
var controller = element.controller('foo');
inputElem = element.find('input');
inputElem.val('foo3');
inputElem.triggerHandler('input'); // fire the input event to update fooValue with 'foo3'
// inputElem.triggerHandler('change'); for IE11
inputElem.triggerHandler({
type: 'keydown',
which: 13
});
expect(controller.fooValue).toBe('foo3');
});
});
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.css" />
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine-html.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="https://code.angularjs.org/1.6.1/angular-mocks.js"></script>
</head>
<body>
</body>
</html>
我已经实现了 foo 组件,其模板有一个输入(绑定到 fooValue 属性)当输入具有焦点时按下 "enter" 键时调用该组件控制器函数 onEnter 的属性。
我遇到的问题是,在输入中插入一个值(即 "foo3")并按下 "enter" 键后,fooValue 是不更新输入值。
这是片段:
var app = angular.module('app', []);
app.component('foo', {
template: '<input ng-model="$ctrl.fooValue" enter-key="$ctrl.onEnter()" />',
controller: function() {
this.onEnter = function() {
// this.fooValue is not updated with input value
};
},
bindings: {
fooValue: '@'
}
});
app.directive('enterKey', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind("keydown keypress", function(event) {
var keyCode = event.which || event.keyCode;
// If enter key is pressed
if (keyCode === 13) {
scope.$apply(function() {
// Evaluate the expression
scope.$eval(attrs.enterKey);
});
}
});
}
};
});
describe('test', function() {
describe('foo', function() {
beforeEach(module('app'));
var element,
inputElem;
beforeEach(inject(function($compile, $rootScope) {
var fooScope = $rootScope.$new();
element = angular.element('<foo foo-value="foo1"></foo>');
element = $compile(element)(fooScope);
fooScope.$digest();
}));
it('should set fooValue with foo3', function() {
var controller = element.controller('foo');
inputElem = element.find('input');
inputElem.val('foo3');
inputElem.triggerHandler({
type: 'keydown',
which: 13
});
expect(controller.fooValue).toBe('foo3');
});
});
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.css" />
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine-html.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="https://code.angularjs.org/1.6.1/angular-mocks.js"></script>
</head>
<body>
</body>
</html>
更新 fooValue 缺少什么?
要更新 fooValue,需要触发 input
事件。如果需要 IE11 支持,请使用 change
事件。
以下片段显示它正在工作:
var app = angular.module('app', []);
app.component('foo', {
template: '<input ng-model="$ctrl.fooValue" enter-key="$ctrl.onEnter()" />',
controller: function() {
this.onEnter = function() {
// this.fooValue is now updated with input value
};
},
bindings: {
fooValue: '@'
}
});
app.directive('enterKey', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind("keydown keypress", function(event) {
var keyCode = event.which || event.keyCode;
// If enter key is pressed
if (keyCode === 13) {
scope.$apply(function() {
// Evaluate the expression
scope.$eval(attrs.enterKey);
});
}
});
}
};
});
describe('test', function() {
describe('foo', function() {
beforeEach(module('app'));
var element,
inputElem;
beforeEach(inject(function($compile, $rootScope) {
var fooScope = $rootScope.$new();
element = angular.element('<foo foo-value="foo1"></foo>');
element = $compile(element)(fooScope);
fooScope.$digest();
}));
it('should set fooValue with foo3', function() {
var controller = element.controller('foo');
inputElem = element.find('input');
inputElem.val('foo3');
inputElem.triggerHandler('input'); // fire the input event to update fooValue with 'foo3'
// inputElem.triggerHandler('change'); for IE11
inputElem.triggerHandler({
type: 'keydown',
which: 13
});
expect(controller.fooValue).toBe('foo3');
});
});
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.css" />
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine-html.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="https://code.angularjs.org/1.6.1/angular-mocks.js"></script>
</head>
<body>
</body>
</html>