Perder alcance al usar ng-include
Tengo este módulo de 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 addLine
función $scope.lineText
is undefined
, esto se puede resolver agregando ng-controller="HomeCtrl"
a partial1.html
, sin embargo, hace que se llame al controlador dos veces. ¿Que me estoy perdiendo aqui?
Como mencionó @Renan, 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 alcance primitiva en el alcance secundario, no en el alcance de HomeCtrl. Este ámbito secundario no es accesible para el ámbito principal/HomeCtrl:
Para almacenar lo que el usuario escribió en la matriz $scope.lines de HomeCtrl, 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 alcance/parcial, creo que debería ser responsable de borrarlo:
<form ng-submit="addLine(lineText); lineText=''">
La función addLine() se convertiría así en:
$scope.addLine = function(lineText) {
$scope.chat.addLine(lineText);
$scope.lines.push({
text: lineText
});
};
Violín .
Alternativas:
- defina una propiedad de objeto en el alcance $ de HomeCtrl y úsela en el parcial:
ng-model="someObj.lineText
; violín - no recomendado, esto es más bien un truco: use $parent en el parcial para crear/acceder a una
lineText
propiedad en HomeCtrl $scope:ng-model="$parent.lineText"
; violín
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é alcance se accede o se manipula.
Esto se debe a ng-include
que se crea un nuevo ámbito secundario, por lo que $scope.lineText
no se modifica. Creo que eso this
se refiere al alcance actual, por lo que this.lineText
debería establecerse.