Эта проблема возникла у меня, когда я не использовал директиву ng-if
для элементов, окружающих элемент textarea. Хотя решение Мэтью верно, причина, по-видимому, в другом. Поиск этой проблемы указывает на этот пост, поэтому я решил поделиться этим.
Если вы посмотрите документацию по AngularJS здесь https://docs.angularjs.org/api/ng/directive/textarea вы можете видеть, что Angular добавляет свою собственную директиву с именем <textarea>
, которая «переопределяет» элемент HTML textarea
по умолчанию. Это новая область, которая вызывает весь беспорядок.
Если у вас есть переменная типа
$scope.myText = 'Dummy text';
в вашем контроллере и привяжите его к элементу textarea
следующим образом
<textarea ng-model="myText"></textarea>
AngularJS будет искать эту переменную в области действия директивы. Его там нет, и поэтому он идет к $parent. Переменная там присутствует и текст вставляется в файл textarea
. При изменении текста в textarea
Angular НЕ изменяет родительскую переменную. Вместо этого он создает новую переменную в области действия директивы, поэтому исходная переменная не обновляется. Если вы привяжете textarea
к родительской переменной, как предложил Мэтью, Angular всегда будет привязываться к правильной переменной, и проблема исчезнет.
<textarea ng-model="$parent.myText"></textarea>
Надеюсь, это прояснит ситуацию для других людей, которые задают этот вопрос и думают: «WTF, я не использую ng-if или любую другую директиву в моем случае!» как я сделал, когда я впервые приземлился здесь;)
Обновление: используйте синтаксис контроллера как
Давно хотел добавить, но все не было времени. Это современный стиль построения контроллеров, и его следует использовать вместо $parent
материала выше. Читайте дальше, чтобы узнать, как и почему.
Начиная с AngularJS 1.2 появилась возможность напрямую ссылаться на объект контроллера вместо использования объекта $scope
. Этого можно добиться, используя следующий синтаксис в HTML-разметке:
<div ng-controller="MyController as myc"> [...] </div>
Популярные модули маршрутизации (например, UI Router) предоставляют аналогичные свойства для своих состояний. Для UI Router вы используете следующее в своем определении состояния:
[...]
controller: "MyController",
controllerAs: "myc",
[...]
Это помогает нам обойти проблему с вложенными или неправильно адресованными областями. Приведенный выше пример будет построен таким образом. Сначала часть JavaScript. Прямо вперед, вы просто не используете ссылку $scope
для установки вашего текста, просто используйте this
для присоединения свойства непосредственно к объекту контроллера.
angular.module('myApp').controller('MyController', function () {
this.myText = 'Dummy text';
});
Разметка для textarea
с синтаксисом controller-as будет выглядеть так:
<textarea ng-model="myc.myText"></textarea>
На сегодняшний день это самый эффективный способ делать подобные вещи, потому что он решает проблему с вложенными областями видимости, заставляя нас считать, на скольких слоях мы находимся в определенный момент. Использование нескольких вложенных директив внутри элементов с директивой ng-controller
могло привести к чему-то подобному при использовании старого способа ссылки на области видимости. И никто не хочет делать это весь день!
<textarea ng-model="$parent.$parent.$parent.$parent.myText"></textarea>
person
marandus
schedule
20.11.2014