angularjs - directivas - ¿Mi ng-model realmente necesita un punto para evitar los problemas de $ child scope?
rootscope angularjs (2)
De acuerdo con https://github.com/angular/angular.js/wiki/Understanding-Scopes , es un problema tratar de vincular datos a primitivas asociadas a su $scope
:
La herencia del alcance es normalmente sencilla, y a menudo ni siquiera necesita saber que está sucediendo ... hasta que pruebe el enlace de datos bidireccional (es decir, elementos de forma, modelo ng) a un primitivo (por ejemplo, número, cadena, boolean) definido en el ámbito principal desde dentro del ámbito hijo. No funciona de la forma en que la mayoría de la gente espera que funcione.
La recomendación es
Este problema con los primitivos se puede evitar fácilmente siguiendo la "mejor práctica" de tener siempre un ''.'' en tus ng-models
Ahora, tengo esta configuración muy simple que infringe estas reglas:
HTML:
<input type="text" ng-model="theText" />
<button ng-disabled="shouldDisable()">Button</button>
JS:
function MyController($scope) {
$scope.theText = "";
$scope.shouldDisable = function () {
return $scope.theText.length >= 2;
};
}
¿Esto es realmente malo? ¿Esto me va a joder de una manera horrible cuando empiezo a tratar de usar telescopios infantiles, de alguna manera?
¿Debo cambiarlo a algo así como
function MyController($scope) {
$scope.theText = { value: "" };
$scope.shouldDisable = function () {
return $scope.theText.value.length >= 2;
};
}
y
<input type="text" ng-model="theText.value" />
<button ng-disabled="shouldDisable()">Button</button>
para que siga la mejor práctica? ¿Qué ejemplo concreto puedes darme para que este me salve de alguna consecuencia horrible que estaría presente en el primero?
Supongamos que tiene los ámbitos M, A y B, donde M es el padre de A y B.
Si uno de (A, B) intenta escribir en el alcance de M, solo funcionará en tipos no primitivos . La razón para esto es que los tipos no primitivos se pasan por referencia .
Los tipos primitivos, por otro lado, no lo son, por lo tanto, intentar escribir en el theText
en el alcance de M creará una nueva propiedad del mismo nombre en el ámbito A o B, respectivamente, en lugar de escribir en M. Si tanto A como B dependen de esto propiedad, se producirán errores, porque ninguno de ellos sería consciente de lo que está haciendo el otro.
Muchas cosas introducen nuevos ámbitos. Digamos que en sus controladores, realmente desea agregar pestañas: la primera pestaña es la representación real, la segunda pestaña es la forma (para que tenga una vista previa en tiempo real).
Usted decide usar una directiva para eso:
<tabs>
<tab name="view">
<pre>{{theText|formatInSomeWay}}</pre>
</tab>
<tab name="edit" focus="true">
<input type="text" ng-model="theText" />
</tab>
</tabs>
Bueno, ¿sabes qué? <tabs>
tiene su propio alcance, ¡y rompió tu controlador uno! Entonces, cuando edite, angular hará algo como esto en js:
$scope.theText = element.val();
que no atravesará la cadena de prototipos para intentar establecer theText
en los padres.
EDITAR: para ser claros, solo estoy usando "pestañas" como ejemplo. Cuando digo " Muchas cosas introducen un nuevo ámbito", me refiero a: ng-include, ng-view, ng-switch, ng-controller (por supuesto), etc.
Entonces, esto podría no ser necesario en este momento , porque aún no tiene alcances secundarios en esa vista, pero no sabe si va a agregar plantillas secundarias o no, lo que eventualmente podría modificar el theText
mismo, causando el problema. Para una futura prueba de su diseño, siempre siga la regla, y no tendrá sorpresa entonces;).