Pérdida de alcance al usar ng-include
Tengo este módulo rutas:
var mainModule = angular.module('lpConnect', []).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/home', {template:'views/home.html', controller:HomeCtrl}).
when('/admin', {template:'views/admin.html', controller:AdminCtrl}).
otherwise({redirectTo:'/connect'});
}]);
HTML de inicio:
<div ng-include src="views.partial1"></div>
partial1
HTML:
<form ng-submit="addLine()">
<input type="text" ng-model="lineText" size="30" placeholder="Type your message here">
</form>
HomeCtrl
:
function HomeCtrl($scope, $location, $window, $http, Common) {
...
$scope.views = {
partial1:"views/partial1.html"
};
$scope.addLine = function () {
$scope.chat.addLine($scope.lineText);
$scope.lines.push({text:$scope.lineText});
$scope.lineText = "";
};
...
}
En la función addLine
$scope.lineText
es undefined
, esto se puede resolver agregando ng-controller="HomeCtrl"
a partial1.html
, sin embargo hace que el controlador sea llamado dos veces. ¿Qué me estoy perdiendo aquí?
4 answers
Esto se debe a ng-include
que crea un nuevo ámbito hijo, por lo que $scope.lineText
no se cambia. Creo que this
se refiere al alcance actual, por lo que this.lineText
debe establecerse.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-06 10:18:05
Como @Renan mencionó, ng-include crea un nuevo ámbito secundario. Este ámbito hereda prototípicamente (consulte las líneas discontinuas a continuación) del ámbito HomeCtrl. ng-model="lineText"
en realidad crea una propiedad de ámbito primitivo en el ámbito hijo, no en el ámbito de HomeCtrl. Este ámbito hijo no es accesible para el ámbito padre/HomeCtrl:
Para almacenar lo que el usuario escribió en el scope scope de HomeCtrl.lines array, le sugiero que pase el valor a la función addLine:
<form ng-submit="addLine(lineText)">
Además, dado que lineText es propiedad de ngInclude scope / partial, creo que debería ser responsable de limpiarlo:
<form ng-submit="addLine(lineText); lineText=''">
Function addLine() se convertiría así en:
$scope.addLine = function(lineText) {
$scope.chat.addLine(lineText);
$scope.lines.push({
text: lineText
});
};
Fiddle .
Alternativas:
- defina una propiedad de objeto en el scope scope de HomeCtrl, y utilícela en el parcial:
ng-model="someObj.lineText
; fiddle - no se recomienda, esto es más un truco: use partial parent en el parcial para crear / acceder a una propiedad
lineText
en el HomeCtrl scope scope:ng-model="$parent.lineText"
; fiddle
Es un poco complicado explicar por qué funcionan las dos alternativas anteriores, pero se explica completamente aquí: ¿Cuáles son los matices de la herencia prototípica / prototípica de alcance en AngularJS?
No recomiendo usar this
en la función addLine (). Se vuelve mucho menos claro a qué ámbito se accede/se manipula.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:12
En lugar de usar this
como sugiere la respuesta aceptada, use $parent
en su lugar. Así que en tu partial1.html
tendrás:
<form ng-submit="$parent.addLine()">
<input type="text" ng-model="$parent.lineText" size="30" placeholder="Type your message here">
</form>
Si desea obtener más información sobre el ámbito en ng-include
u otras directivas, consulte esto: https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-include
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-05 05:55:10
He descubierto cómo solucionar este problema sin mezclar datos de alcance primario y secundario.
Establecer un ng-if
en el elemento ng-include
y establecerlo en una variable de ámbito.
Por ejemplo :
<div ng-include="{{ template }}" ng-if="show"/>
En su controlador, cuando haya establecido todos los datos que necesita en su sub ámbito, establezca show en true
. El ng-include
copiará en este momento el conjunto de datos en su ámbito y lo establecerá en su sub ámbito.
La regla general es reducir los datos del ámbito más profundo que el ámbito, de lo contrario, tiene esto situación.
Max
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-04 13:39:28