Подтвердить что ты не робот

Директива AngularJS: выражение 'undefined', используемое с директивой... не назначается

Я уже 2 недели Angular noob, и я пытаюсь выполнить свою первую директиву уже более суток.: P Я прочитал этот и этот, который, похоже, содержит хорошие директивы и множество ответов Stackoverflow, но я не могу заставить это работать.

<div ng-app="App" ng-controller="Main">
  <textarea caret caret-position="uiState.caretPosition"></textarea>
  {{uiState.caretPosition}}
</div>

и

angular.module('App', [])
  .controller('Main', ['$scope', function ($scope) {
    $scope.uiState = {};
    $scope.uiState.caretPosition = 0;
  }])


  .directive('caret', function() {
    return {
      restrict: 'A',
      scope: {caretPosition: '='},
      link: function(scope, element, attrs) {
        var $el = angular.element(element);
        $el.on('keyup', function() {
          scope.caretPosition = $el.caret();
        });
      }
    };
  }); 

Fiddle здесь. Я в основном пытаюсь получить позицию каретки в текстовом поле. Я использую этот плагин jQuery в скрипте (источник метода .caret(), который должен просто вернуть число).

Мои вопросы

  • Мне нужна директива? Бен Надел говорит, что лучшие директивы - это те, которые вам не нужно писать (аминь к этому!)
  • Если да, то это правильный способ пойти по директиве? Т.е. изолированная область с двухсторонней связанной переменной?
  • Если да, когда я запускаю этот код локально, я продолжаю получать ошибку Expression 'undefined' used with directive 'caret' is non-assignable!. Я прочитал документ, и насколько я могу судить, я следил за инструкциями о том, как исправить это безрезультатно.
  • БОНУС: Почему в jsfiddle я не получаю такой ошибки. Скрипка просто терпит неудачу. Что с этим?

Спасибо!

4b9b3361

Ответ 1

Вы были близки. Основная проблема заключается в изменении переменной области видимости внутри события, о котором angular не знает. Когда это событие произойдет, вы должны сообщить angular, что что-то изменилось с помощью scope.$apply.

  $el.on('keyup', function() {
      scope.$apply( function() {
        scope.caretPosition = $el.caret();
      });
  });

Рабочая скрипка здесь

По вопросам:

  • да, я не думаю, что есть способ написать директиву для этого.
  • В этом случае это кажется прекрасным.
  • Не уверен, в jsfiddle проблем нет. Похоже, вы где-то устанавливаете carat="something"? проверьте, чтобы html был таким же, как в скрипте.
  • так же, как 3

Также обратите внимание, что если вы нажмете и переместите курсор, он не будет обновляться, потому что он только прослушивает клавиатуру.

Ответ 2

Мое решение было труднее узнать здесь, но проще реализовать. Мне пришлось изменить его на эквивалент:

  scope: {caretPosition: '=?'},

(Обратите внимание, что знак вопроса делает атрибут необязательным. До 1.5 это, очевидно, не требовалось.)