Как обновить свойство компонента angularjs, привязанное к входному набору с помощью element.val в тесте - PullRequest
0 голосов
/ 27 мая 2018

Я реализовал компонент foo , шаблон которого имеет вход (связанный с свойством fooValue ) с атрибутом директивы, который вызывает функцию контроллера компонента onEnter когда клавиша «ввод» нажата, когда ввод имеет фокус.

Проблема, которую я получаю, заключается в том, что после ввода значения во вход (например, «foo3») и нажатия клавиши «ввод», 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?

1 Ответ

0 голосов
/ 27 мая 2018

Для обновления 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>
...