No se puede obtener el valor de textarea en angularjs

Aquí está mi plnkr: http://plnkr.co/edit/n8cRXwIpHJw3jUpL8PX5?p=preview Tienes que hacer clic en un elemento li y aparecerá el formulario. Ingrese una cadena aleatoria y presione ‘agregar aviso’. En lugar del texto textarea, no estará definido.

Margen:

  • {{ ticket.text }}

Parte JS:

 $scope.createNotice = function(ticket){ alert($scope.noticeText); } 

devuelve ‘indefinido’. Noté que esto no funciona al usar ui-if de angular-ui. ¿Alguna idea de por qué esto no funciona? ¿Como arreglarlo?

Tu problema está en la parte ui-if. Parece que angular-ui crea un nuevo scope para cualquier cosa dentro de esa directiva, por lo que para acceder al scope principal, debe hacer algo como esto:

  

En lugar de

  

Este problema me ocurrió sin utilizar la directiva ng-if en los elementos que rodean el elemento textarea. Si bien la solución de Mateo es correcta, la razón parece ser otra. La búsqueda de ese problema apunta a esta publicación, así que decidí compartir esto.

Si observa la documentación de AngularJS aquí https://docs.angularjs.org/api/ng/directive/textarea , puede ver que Angular agrega su propia directiva llamada que “anula” el elemento HTML textarea predeterminado. Este es el nuevo scope que causa todo el desastre.

Si tienes una variable como

 $scope.myText = 'Dummy text'; 

en su controlador y vincular eso al elemento textarea como este

  

AngularJS buscará esa variable en el scope de la directiva. No está allí y por lo tanto él baja a $ parent. La variable está presente allí y el texto se inserta en el área de textarea . Al cambiar el texto en el área de textarea , Angular NO cambia la variable principal. En cambio, crea una nueva variable en el scope de la directiva y, por lo tanto, la variable original no se actualiza. Si vincula el área de textarea a la variable principal, como lo sugiere Mateo, Angular siempre se vinculará con la variable correcta y el problema desaparecerá.

  

Espero que esto aclare las cosas para otras personas que lleguen a esta pregunta y piensen: “¡WTF, no estoy usando ng-if ni ninguna otra directiva en mi caso!” como lo hice cuando llegué aquí por primera vez;)

Actualización: use la syntax del controlador

Quería agregar esto mucho antes pero no encontré tiempo para hacerlo. Este es el estilo moderno de los controladores de construcción y debería usarse en lugar de las cosas $parent anteriores. Sigue leyendo para descubrir cómo y por qué .

Desde AngularJS 1.2 existe la posibilidad de referenciar el objeto del controlador directamente en lugar de usar el objeto $scope . Esto se puede lograr mediante el uso de esta syntax en el marcado HTML:

 
[...]

Los módulos de enrutamiento populares (es decir, el enrutador UI) proporcionan propiedades similares para sus estados. Para el enrutador UI, use lo siguiente en su definición de estado:

 [...] controller: "MyController", controllerAs: "myc", [...] 

Esto nos ayuda a eludir el problema con ámbitos nesteds o direccionados incorrectamente. El ejemplo anterior se construiría de esta manera. Primero la parte de JavaScript. En línea recta, usted no usa la referencia $scope para configurar su texto, solo use this para adjuntar la propiedad directamente al objeto del controlador.

 angular.module('myApp').controller('MyController', function () { this.myText = 'Dummy text'; }); 

El marcado para el área de textarea con la syntax de controlador se vería así:

  

Esta es la forma más eficiente de hacer este tipo de cosas hoy, porque resuelve el problema con ámbitos nesteds, lo que nos hace contar cuántas capas de profundidad tenemos en un determinado punto. El uso de múltiples directivas anidadas dentro de los elementos con una directiva ng-controller podría haber llevado a algo así cuando se usa la antigua forma de referenciar ámbitos. ¡Y nadie realmente quiere hacer eso todo el día!

  

Vincule el área de texto a la propiedad de una variable de ámbito en lugar de directamente a una variable de ámbito:

controlador:

 $scope.notice = {text: ""} 

modelo:

  

De hecho, es ui-if eso crea el problema. Angular si las directivas destruyen y vuelven a crear porciones del árbol dom basadas en la expresión. Esto es lo que crea el nuevo scope y no la directiva textarea como sugirió Marandus.

Aquí hay una publicación sobre las diferencias entre ngIf y ngShow que describe bien este: cuál es la diferencia entre ng-if y ng-show / ng-hide .