Как проверить эту директиву?

Как я могу проверить эту директиву?

angular.module('uiApp')
.directive('uppercase', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ngModelCtrl) {
            var uppercase = function (value) {
                var uppercase = value.toUpperCase();
                if (uppercase !== value) {
                    ngModelCtrl.$setViewValue(uppercase);
                    ngModelCtrl.$render();
                }
                return uppercase;
            };
            ngModelCtrl.$parsers.push(uppercase);
        }
    };
});

Я пробовал этот подход, но он не работает:

it('should transform to uppercase', inject(function ($compile) {
    element = angular.element('<input type="text" ng-model="test" ng-init="test=\'test\'" uppercase>');
    element = $compile(element)(scope);
    expect(element.text()).toBe('TEST');
}));

person amb    schedule 14.05.2014    source источник


Ответы (2)


У меня есть его:

it('should transform to uppercase', inject(function ($compile) {
    scope.test = '';
    element = angular.element('<input type="text" ng-model="test" uppercase>');
    element = $compile(element)(scope);
    element.val('test').triggerHandler('input');
    expect(element.val()).toBe('TEST');
    expect(scope.test).toBe('TEST');
}));

И это работает. По-видимому, trigger('input') является ключом.

person amb    schedule 14.05.2014

Вам нужно добавить uppercase к $formatters в функции ссылки, а не $parsers:

ngModelCtrl.$formatters.push(uppercase);

Затем протестируйте его следующим образом:

it('should transform to uppercase', inject(function ($compile, $rootScope, $timeout) {
    $rootScope.test = 'test';
    element = angular.element('<input type="text" ng-model="test" uppercase>');
    element = $compile(element)($rootScope);
    $rootScope.$apply();
    expect(element.val()).toBe('TEST');
}));
person Ye Liu    schedule 14.05.2014
comment
Нет, я все еще получаю сообщение об ошибке Expected '' to be 'TEST'. - person amb; 14.05.2014
comment
Та же ошибка. Если я добавлю $rootScope.$digest() перед $rootScope.$apply(...), по крайней мере, у меня будет ошибка Expected 'test' to be 'TEST' - person amb; 14.05.2014
comment
@amb Я обнаружил, что ваша реализация не совсем правильная, я обновил свой ответ, чтобы решить эту проблему. - person Ye Liu; 14.05.2014
comment
Я думаю, что есть еще недостаток в реализации. Я считаю, что он должен работать с ng-init. Но если вы посмотрите на этот plunker, вы также увидите, что значение представления не обновляется быть в верхнем регистре при первой загрузке страницы - person JoseM; 14.05.2014
comment
@JoseM и Е Лю, да, так и задумано. Чтобы применить верхний регистр при загрузке страницы, я могу позвонить в конце: uppercase(scope[attrs.ngModel]); - person amb; 14.05.2014
comment
@JoseM Есть небольшая разница между вашим орудием и орудием. Если вы измените ngModelCtrl.$viewValue = uppercase` на ngModelCtrl.$setViewValue(uppercase), вы увидите то, что ожидаете. - person Ye Liu; 14.05.2014
comment
@Ye Liu Я снова протестировал ваш код, но он все равно не работает, даже если я изменю директиву на верхний регистр при загрузке страницы. Несмотря на то, что я, наконец, понял это, я благодарю вас. - person amb; 14.05.2014
comment
@amb Этот тест в вашем собственном ответе предполагает, что ваша директива преобразует пользовательский ввод, но тест в вашем исходном вопросе преобразует значение из ngModel. Какова реальная цель вашей директивы? - person Ye Liu; 14.05.2014
comment
@YeLiu Значение из ngModel — это ввод пользователя или значение из модели. Поскольку это двусторонняя привязка данных, она будет заглавными буквами вводить значение из пользовательского ввода или значение из модели, но не при загрузке первой страницы (учитывая значение из модели). Я не понимаю, что непонятно. - person amb; 14.05.2014
comment
@YeLiu после того, как я просмотрел свой первоначальный тест, я понял, почему это сбивает с толку. Но идея в том, что он должен работать в обе стороны — пользовательский ввод и модель, но только после загрузки первой страницы. Я понятия не имел, что писать в тесте, так что это был плохой пример. - person amb; 14.05.2014
comment
@YeLiu Я проголосовал за ваш ответ, так как он мне помог. - person amb; 14.05.2014
comment
@amb Я создал plunk, чтобы показать вам разницу между $parsers и $formatters. $parsers отвечают за получение изменений dom в модели, $formatters отвечают за форматирование значения модели в dom. Если вы хотите преобразовать текст в обоих направлениях, вам нужно добавить заглавные буквы к $parsers и $formatters. - person Ye Liu; 14.05.2014
comment
@YeLiu спасибо. Да, я забыл о $formatters. Меня больше интересовало изменение пользовательского ввода, поскольку данные, извлеченные из базы данных, уже были в верхнем регистре. Директива следует этому примеру: "> stackoverflow.com/questions/15242592/ - person amb; 14.05.2014
comment
@YeLiu Думаю, я оставлю это как есть, поскольку данные из модели всегда будут в верхнем регистре. - person amb; 14.05.2014