Невозможно получить значение textarea в angularjs
Вот мой plnkr: http://plnkr.co/edit/n8cRXwIpHJw3jUpL8PX5?p=preview Вам нужно щелкнуть элемент li и появится форма. Введите случайную строку и нажмите "добавить уведомление". Вместо текста textarea вы получите undefined.
Разметка:
<ul>
<li ng-repeat="ticket in tickets" ng-click="select(ticket)">
{{ ticket.text }}
</li>
</ul>
<div ui-if="selectedTicket != null">
<form ng-submit="createNotice(selectedTicket)">
<textarea ng-model="noticeText"></textarea>
<button type="submit">add notice</button>
</form>
</div>
Часть JS:
$scope.createNotice = function(ticket){
alert($scope.noticeText);
}
возвращает 'undefined'. Я заметил, что это не работает при использовании ui-if angular -ui. Любые идеи, почему это не работает? Как это исправить?
Ответы
Ответ 1
Ваша проблема заключается в части пользовательского интерфейса. Angular-ui создает новую область видимости для чего-либо в этой директиве, поэтому для доступа к родительской области видимости вы должны сделать что-то вроде этого:
<textarea ng-model="$parent.noticeText"></textarea>
Вместо
<textarea ng-model="noticeText"></textarea>
Ответ 2
Эта проблема произошла со мной, не применяя директиву 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>
Ответ 3
Привяжите текстовое поле к переменной области видимости , а не непосредственно к переменной области видимости:
контроллер:
$scope.notice = {text: ""}
шаблон:
<textarea ng-model="notice.text"></textarea>
Ответ 4
Это, действительно, ui-if
создает проблему. Angular, если директивы уничтожают и воссоздают части дерева dom на основе выражения. Это создало новую область действия, а не директив textarea, как предположил марандус.
Вот сообщение о различиях между ngIf и ngShow, которые описывают это хорошо в чем разница между ng-if и ng-show/ng-hide.