Директива 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 я не получаю такой ошибки. Скрипка просто терпит неудачу. Что с этим?
Спасибо!
Ответы
Ответ 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 это, очевидно, не требовалось.)