Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

unidades:04_masdirectivas:06_ngif [2014/07/31 18:53]
admin [Herencia de $scope]
unidades:04_masdirectivas:06_ngif [2014/08/29 22:58] (actual)
admin
Línea 1: Línea 1:
 ====== 4.6 ng-if ====== ====== 4.6 ng-if ======
-La directiva ''​ng-if''​ nos permite que exista o no un tag en la página. Podríamos pensar que es similar a [[unidades:​02_angular:​06_ngshow|ng-show]] o [[unidades:​02_angular:​07_nghide|ng-hide]],​ pero éstas últimas directivas simplemente los ocultan mediante CSS mientras que ''​ng-if'' ​lo elimina del DOM o lo vuelve a añadir.+La directiva ''​ng-if''​ nos permite que exista o no un tag en la página. Podríamos pensar que es similar a [[unidades:​02_angular:​06_ngshow|ng-show]] o [[unidades:​02_angular:​07_nghide|ng-hide]],​ pero éstas últimas directivas simplemente los ocultan mediante CSS mientras que ''​ng-if'' ​los elimina del DOM o los vuelve a añadir.
  
-Esta directiva no debería tener mucho que explicar pero realmente tiene un detalle que la hace muy importante. Crea un nuevo ''​$scope''​ heredando de nuestro ''​$scope''​ del controlador. ​Esto realmente tiene una importancia enorme ya que implica saber como funciona la herencia de ''​$scope''​ en JavaScript y AngularJS.+Esta directiva no debería tener mucho que explicar pero realmente tiene un detalle que la hace muy importante. Crea un nuevo ''​$scope''​ heredando de nuestro ''​$scope''​ del controlador. ​Ésto realmente tiene una importancia enorme ya que implica saber cómo funciona la herencia de ''​$scope''​ en JavaScript y AngularJS.
  
 Vamos a ver primeramente un ejemplo y comprobaremos que hay algo que funciona mal. Vamos a ver primeramente un ejemplo y comprobaremos que hay algo que funciona mal.
  
-En el ejemplo prueba a escribir algo en el nombre y en el apellido. ​Veras como el apellido ​si que se modifica en las 2 líneas ​ pero el nombre **no** se modifica en uno de los casos. ​+En el ejemplo prueba a escribir algo en el nombre y en el apellido. ​Verás cómo el apellido ​sí se modifica en las 2 líneas ​ pero el nombre **no** se modifica en uno de los casos. ​
  
 {{url>​http://​embed.plnkr.co/​H0O8Jn1DnwsbpFnOb8Pk}} {{url>​http://​embed.plnkr.co/​H0O8Jn1DnwsbpFnOb8Pk}}
  
-¿Que hay distinto en los 2 ejemplos? Simplemente que en el modelo del apellido hay un punto y en el del nombre no. ¿Recuerdas la advertencia del tema [[unidades:​02_angular:​04_formulario]]. Decía lo siguiente:+¿Qué ​hay distinto en los 2 ejemplos? Simplemente que en el modelo del apellido hay un punto y en el del nombreno.  
 + 
 +<sxh html;​title:​index.html;​highlight:​ [16,​18,​27,​29]>​ 
 +<​!DOCTYPE html> 
 +<html ng-app="​app">​ 
 +  
 +<​head>​ 
 +  <script src="//​ajax.googleapis.com/​ajax/​libs/​angularjs/​1.2.19/​angular.js"></​script>​ 
 +  <script src="​script.js"></​script>​ 
 +</​head>​ 
 +  
 +<body ng-controller="​PruebaController">​ 
 + 
 +<input type="​checkbox"​ ng-model="​showNombre">​¿Mostrar nombre? 
 +<​br>​ 
 +<div ng-if="​showNombre">​ 
 +  Nombre: <input ng-model="​nombre"​ > 
 +  <​br>​ 
 +  El valor de "​nombre"​ en el $scope del "​ng-if"​ es : {{nombre}} 
 +</​div>​ 
 +El valor de "​nombre"​ en el $scope del "​Controlador"​ es : <​strong>​{{nombre}}</​strong>​ 
 + 
 +<​hr>​ 
 + 
 +<input type="​checkbox"​ ng-model="​modelo.showApellido">​¿Mostrar apellido? 
 +<​br>​ 
 +<div ng-if="​modelo.showApellido">​ 
 +  Apellido: <input ng-model="​modelo.apellido"​ > 
 +  <​br>​ 
 +  El valor de "​apellido"​ en el $scope del "​ng-if"​ es : {{modelo.apellido}} 
 +</​div>​ 
 +El valor de "​apellido"​ en el $scope del "​Controlador"​ es : {{modelo.apellido}} 
 + 
 +</​body>​ 
 +  
 +</​html>​ 
 +</​sxh>​ 
 + 
 +  * Línea 16: La expresión ''​%%{{nombre%%}}''​ hace referencia al nuevo ''​$scope''​ creado dentro de la directiva ''​ng-if''​. 
 +  * Línea 18: La expresión ''​%%{{nombre%%}}''​ hace referencia al ''​$scope''​ del controlador. 
 + 
 +  * Línea 27: La expresión ''​%%{{apellido%%}}''​ hace referencia al nuevo ''​$scope''​ creado dentro de la directiva ''​ng-if''​. 
 +  * Línea 29: La expresión ''​%%{{apellido%%}}''​ hace referencia al ''​$scope''​ del controlador. 
 + 
 +<sxh js;​title:​script.js;​highlight:​ [4,8]> 
 +var app = angular.module("​app",​ []); 
 +   
 +app.controller("​PruebaController",​ function($scope) { 
 +  $scope.nombre="​Carlos";​ 
 +  $scope.showNombre=true;​ 
 +   
 +  $scope.modelo={ 
 +    apellido:"​Perez",​ 
 +    showApellido:​true ​  
 +  } 
 +  
 +}); 
 +</​sxh>​ 
 + 
 +  * Linea 4: La propiedad ''​nombre''​ no está dentro de un objeto. 
 +  * Línea 8: La propiedad ''​apellido''​ está dentro de un objeto. 
 + 
 +¿Recuerdas la advertencia del tema [[unidades:​02_angular:​04_formulario]]. Decía lo siguiente:
  
 **//Si el valor de tu directiva ng-model no incluye un punto es que está mal//** **//Si el valor de tu directiva ng-model no incluye un punto es que está mal//**
Línea 16: Línea 78:
 Ahora vamos a explicar del motivo de esta advertancia. ​ Ahora vamos a explicar del motivo de esta advertancia. ​
  
-Voy a volver a recordar que dentro de una directiva ''​ng-if''​ se crea un nuevo ''​$scope''​ que hereda de nuestro ''​$scope''​ del controlador. ​Esto significa que cuando estamos poniendo los tag ''<​input>''​ con el ''​ng-model''​. El nombre de la propiedad a la que hace referencia no es a nuestro ''​$scope''​ de nuestro controlador sino al nuevo ''​$scope''​ que hay dentro del ''​ng-if''​. Lo bueno de todo ello es que el nuevo ''​$scope''​ que hay dentro del ''​ng-if''​ ha copiado ​todos los valores que había en el ''​$scope''​ del controlador. +Voy a volver a recordar que dentro de una directiva ''​ng-if''​ se crea un nuevo ''​$scope''​ que hereda de nuestro ''​$scope''​ del controlador. ​Ésto significa que cuando estamos poniendo los tag ''<​input>''​ con el ''​ng-model''​, el nombre de la propiedad a la que hace referencia no es a nuestro ''​$scope''​ de nuestro controlador sino al nuevo ''​$scope''​ que hay dentro del ''​ng-if''​. Lo bueno de todo ello es que el nuevo ''​$scope''​ que hay dentro del ''​ng-if''​ ha heredado ​todos los valores que había en el ''​$scope''​ del controlador.
 ===== Herencia de $scope ===== ===== Herencia de $scope =====
-Lo importante ahora es comprender ​como se ha hecho dicha herencia. Es algo tan //chapuza// que lo que hace es copiar simplemente el valor de todas las propiedades. El problema es que si una propiedad **NO** es un puntero a un objeto ​resulta que tenemos ​2 propiedades distintas que tienen ahora 2 valores ​independiente.+Lo importante ahora es comprender ​cómo se ha hecho dicha herencia. Es algo tan //chapuza// que lo que hace es copiar simplemente el valor de todas las propiedades. El problema es que si una propiedad **NO** es un puntero a un objeto resulta que tendremos ​2 propiedades distintas que tienen ahora 2 valores ​independientes.
  
 <uml> <uml>
Línea 40: Línea 101:
 </​uml>​ </​uml>​
  
-Fíjate en el diagrama UML de objetos que se ha creado. Ahora cada ''​$scope''​ tiene las propiedades repetidas pero si esa propiedad apuntaba a un objeto, en ambos casos se apunta al mismo objeto ​pero si la propiedad no era un objeto , en cada ''​$scope''​ cada propiedad es independiente.+Fíjate en el diagrama UML de objetos que se ha creado. Ahora cada ''​$scope''​ tiene las propiedades repetidaspero si esa propiedad apuntaba a un objeto, en ambos casos se apunta al mismo objeto. Ahora bien, si la propiedad no era un objeto , en cada ''​$scope''​ cada propiedad es independiente.
  
 Es decir que la propiedad ''​nombre''​ del ''​$scope''​ del ''​ng-if''​ es distinta de la propiedad ''​nombre''​ del ''​$scope''​ del controlador , por lo tanto un cambio en la propiedad ''​nombre''​ del ''​$scope''​ del ''​ng-if''​ no modifica el ''​$scope''​ del controlador. Es decir que la propiedad ''​nombre''​ del ''​$scope''​ del ''​ng-if''​ es distinta de la propiedad ''​nombre''​ del ''​$scope''​ del controlador , por lo tanto un cambio en la propiedad ''​nombre''​ del ''​$scope''​ del ''​ng-if''​ no modifica el ''​$scope''​ del controlador.
  
-Sin embargo la propiedad ''​modelo.apellido''​ del ''​$scope''​ del ''​ng-if''​ es la misma que la propiedad ''​modelo.apellido''​ del ''​$scope''​ del controlador , por lo tanto un cambio en la propiedad ''​modelo.apellido''​ del ''​$scope''​ del ''​ng-if''​ **SI** modifica el ''​$scope''​ del controlador ​ya que ambos apuntan al mismo objeto.+Sin embargo la propiedad ''​modelo.apellido''​ del ''​$scope''​ del ''​ng-if''​ es la misma que la propiedad ''​modelo.apellido''​ del ''​$scope''​ del controlador ​ya que ambas apuntan al mismo objeto, por lo tanto un cambio en la propiedad ''​modelo.apellido''​ del ''​$scope''​ del ''​ng-if''​ **SI** modifica el ''​$scope''​ del controlador.
  
-de todo ésto se deduce que siempre deberían estar nuestras propiedades dentro de objetos y por eso la frase:+De todo ésto se deduce que siempre deberían estar nuestras propiedades dentro de objetos y por eso la frase:
  
 **//Si el valor de tu directiva ng-model no incluye un punto es que está mal//** **//Si el valor de tu directiva ng-model no incluye un punto es que está mal//**
  
 Ya que tener un punto significa que los datos están dentro de un objeto. Ya que tener un punto significa que los datos están dentro de un objeto.
 +
 +<note warning>
 +Espero que todo ésto se haya comprendido porque es uno de los mayores motivos de errores en AngularJS.
 +</​note>​
 +
 +<note tip>
 +Realmente el modelo de objetos que hemos presentado en el diagrama UML ahí no se corresponde exactamente con la realidad ya que no se hace copia del valor en el ''​$scope''​ del ''​ng-if''​ hasta que no se cambia el valor. Mientras tanto sigue apuntando al ''​$scope''​ del controlador mediante la cadena de prototipos de JavaScript.
 +
 +Ésto último implica que si primero se hace un cambio en la propiedad ''​nombre''​ del ''​$scope''​ del controlador sí que se vería reflejada en la propiedad ''​nombre''​ del ''​$scope''​ del ''​ng-if''​. Pero una vez se modifica la propiedad ''​nombre''​ del ''​$scope''​ del ''​ng-if''​ ya se hacen independientes.
 +
 +Cambia el ejemplo de esta forma y mira a ver lo que ocurre cuando primero cambias un input u otro del nombre.
 +
 +<sxh html;​highlight:​ [3]>
 +<input type="​checkbox"​ ng-model="​showNombre">​¿Mostrar nombre?
 +<br>
 +Nombre: <input ng-model="​nombre"​ >
 +<div ng-if="​showNombre">​
 +  Nombre: <input ng-model="​nombre"​ >
 +  <br>
 +  El valor de "​nombre"​ en el $scope del "​ng-if"​ es : {{nombre}}
 +</​div>​
 +El valor de "​nombre"​ en el $scope del "​Controlador"​ es : <​strong>​{{nombre}}</​strong>​
 +
 +</​sxh>​
 +Añade la línea 3 al ejemplo y mira lo que ocurre.
 +</​note>​
 +
 +===== Referencias =====
 +  * [[https://​docs.angularjs.org/​api/​ng/​directive/​ngIf|ng-if]]
 +  * [[https://​docs.angularjs.org/​guide/​scope#​scope-hierarchies|/​ Developer Guide / Scopes / Scope Hierarchies]]
 +  * [[https://​github.com/​angular/​angular.js/​wiki/​Understanding-Scopes|Understanding Scopes]]
unidades/04_masdirectivas/06_ngif.1406825621.txt.gz · Última modificación: 2014/07/31 18:53 por admin
Ir hasta arriba
CC Attribution-Share Alike 3.0 Unported
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0