javascript - tag - Perdendo o escopo ao usar ng-include



title attribute html (3)

Eu tenho este módulo de rotas:

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 em casa:

<div ng-include src="views.partial1"></div>

HTML partial1 :

<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 = "";
    };
...
}

Na função addLine $scope.lineText é undefined , isso pode ser resolvido adicionando ng-controller="HomeCtrl" a ng-controller="HomeCtrl" , no entanto, faz com que o controlador seja chamado duas vezes. O que estou perdendo aqui?


Answer #1

Como mencionado por @Renan, ng-include cria um novo escopo filho. Esse escopo cria heróis prototípicos (consulte as linhas tracejadas abaixo) do escopo HomeCtrl. ng-model="lineText" na verdade cria uma propriedade de escopo primitiva no escopo filho, não no escopo do HomeCtrl. Este escopo filho não está acessível ao escopo pai / HomeCtrl:

Para armazenar o que o usuário digitou no array $ scope.lines do HomeCtrl, sugiro que você passe o valor para a função addLine:

 <form ng-submit="addLine(lineText)">

Além disso, como o lineText pertence ao ngInclude scope / partial, acho que ele deve ser responsável por limpá-lo:

 <form ng-submit="addLine(lineText); lineText=''">

A função addLine () se tornaria assim:

$scope.addLine = function(lineText) {
    $scope.chat.addLine(lineText);
    $scope.lines.push({
        text: lineText
    });
};

Fiddle .

Alternativas:

  • define uma propriedade de objeto no $ scope do HomeCtrl, e usa isso no partial: ng-model="someObj.lineText ; fiddle
  • não recomendado, isso é mais um hack: use $ parent na parte parcial para criar / acessar uma propriedade lineText no HomeCtrl $ scope: ng-model="$parent.lineText" ; fiddle

É um pouco complicado explicar por que as duas alternativas acima funcionam, mas é totalmente explicado aqui: Quais são as nuances do escopo do protótipo / herança prototípica no AngularJS?

Eu não recomendo usar this na função addLine (). Torna-se muito menos claro qual escopo está sendo acessado / manipulado.


Answer #2

Em vez de usar this como a resposta aceita sugere, use $parent lugar. Então, no seu partial1.html você terá:

<form ng-submit="$parent.addLine()">
    <input type="text" ng-model="$parent.lineText" size="30" placeholder="Type your message here">
</form>

Se você quiser saber mais sobre o escopo em ng-include ou outras diretivas, verifique: https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-include


Answer #3

Isso ocorre por causa do ng-include que cria um novo escopo filho, portanto $scope.lineText não é alterado. Eu acho que this se refere ao escopo atual, então this.lineText deve ser definido.





angularjs-ng-include