Perder alcance al usar ng-include

Resuelto Shlomi Schwartz asked hace 12 años • 4 respuestas

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>

partial1HTML:

<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 addLinefunción $scope.lineTextis 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?

Shlomi Schwartz avatar Jul 10 '12 18:07 Shlomi Schwartz
Aceptado

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:

ng-incluir alcance

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 lineTextpropiedad 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 thisen la función addLine(). Se vuelve mucho menos claro a qué alcance se accede o se manipula.

Mark Rajcok avatar Jan 03 '2013 20:01 Mark Rajcok

Esto se debe a ng-includeque se crea un nuevo ámbito secundario, por lo que $scope.lineTextno se modifica. Creo que eso thisse refiere al alcance actual, por lo que this.lineTextdebería establecerse.

Renan Tomal Fernandes avatar Jul 10 '2012 15:07 Renan Tomal Fernandes