gpt4 book ai didi

angularjs - 使用 $parsers(和 $formatters)对指令进行单元测试

转载 作者:行者123 更新时间:2023-12-02 20:14:47 24 4
gpt4 key购买 nike

我有以下指令:

!(function (window, angular) {
'use strict';

/**
* @ngdoc directive
* @name app.directive:social
* @description
* # social
*/
angular.module('app')
.directive('social', function(social_network_conf) {
return {
restrict: 'A',
scope: {
social: "@"
},
require: 'ngModel',
controller: function($scope, $element){
//for tests only
$scope.render = function(){
//how to I get the ngModel here
ngModel.$render();
};

$scope.setViewValue = function(val){
ngModel.$setViewValue(val);
};
},
link: function(scope, element, attr, ngModel) {

ngModel.$formatters.push(function(value) {// from model to view
value = value.trim();
if(value){
if (value.indexOf(social_network_conf.matcher) === 0){
var split_link = value.split(social_network_conf.divider);
return split_link[split_link.length-1];
}
else{
return value;
}
}
});

ngModel.$parsers.push(function(value) { // from view to model
value = value.trim();
if(value){
if (value.indexOf(social_network_conf.matcher) === 0){
return value;
}
else{
return social_network_conf.prefix + scope.social +
social_network_conf.suffix + value;
}
}
});
}
};
});
}(window, window.angular));

测试如下:

'use strict';

describe('Directive: social', function () {

// load the directive's module
beforeEach(module('app'));

var element,
social_network_conf,
linker,
scope,
$httpBackend;

beforeEach(inject(function ($rootScope, _$httpBackend_, _social_network_conf_) {
scope = $rootScope.$new();
social_network_conf = _social_network_conf_;
//Must be an object to make use of prototypical inheritence for out-side-of-isolate-scope access
scope.models = {};

$httpBackend = _$httpBackend_;
$httpBackend.whenGET(/views\/social.html/).respond('<div></div>');
$httpBackend.whenGET(/views\/navigation.html/).respond('<div></div>');

}));

it('It should convert ngModel into full HTTP address notation', inject(function ($compile) {
element = angular.element('<input social="test_network" ng-model="models.test_network"></social>');
linker = $compile(element);
element = linker(scope);
scope.$apply(function(){
element.val('test');
});
scope.$digest();
expect(scope.models.test_network).toBe(social_network_conf.prefix + 'test' +
social_network_conf.suffix);
// expect(element.text()).toBe('this is the social directive');
}));
});

问题在于这些行:

scope.$apply(function(){
element.val('test');
});

实际上并不调用我定义的 $parser。

尽管使用API​​为指令创建了一个 Controller 来调用ngModel.$renderngModel.$setViewValue,但我无法在指令 Controller 没有丑陋的黑客攻击。

最佳答案

2种可能的解决方案:

首先是将元素包装在表单中,并为输入字段和表单分配一个 name 属性,然后按如下方式访问输入字段:

scope.form_name.input_name.$setViewValue('value')

工作代码:

'use strict';

describe('Directive: social', function () {

// load the directive's module
beforeEach(module('app'));

var element,
social_network_conf,
linker,
scope,
$compile,
$body,
html,
$httpBackend;

beforeEach(inject(function ($rootScope, _$compile_, _$httpBackend_, _social_network_conf_) {
scope = $rootScope.$new();
social_network_conf = _social_network_conf_;
//Must be an object to make use of prototypical inheritence for out-side-of-isolate-scope access
scope.models = {};
$compile = _$compile_;
$httpBackend = _$httpBackend_;
$body = $('body');
$httpBackend.whenGET(/views\/social.html/).respond('<div></div>');
$httpBackend.whenGET(/views\/navigation.html/).respond('<div></div>');
$body.empty();
html = '<form name="testForm">' +
'<input social="test_network" name="test" ng-model="models.test_network">' +
'</form>';

}));

it('It should convert ngModel into full HTTP address notation', function () {

element = angular.element(html);
linker = $compile(element);
element = linker(scope);

var viewValue = 'test',
input = element.find('input');

scope.models.test_network = viewValue;
scope.$digest();

scope.testForm.test.$setViewValue(viewValue);

scope.$digest();
expect(scope.models.test_network).toBe(social_network_conf.prefix + input.isolateScope().social +
social_network_conf.suffix + viewValue);

});

或者,第二个提供了在元素上分派(dispatch)输入事件 - 对我来说 Angular 1.3 不起作用。This YouTube video 中对此进行了演示。 .

 element.val('test');
element.trigger('input');

关于angularjs - 使用 $parsers(和 $formatters)对指令进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26659042/

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