it-swarm.com.ru

Потеря области при использовании ng-include

У меня есть этот модуль маршрутов:

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:

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

В функции addLine$scope.lineText равен undefined, это можно решить, добавив ng-controller="HomeCtrl" к partial1.html, однако это приводит к тому, что контроллер вызывается дважды. Что мне здесь не хватает?

179
Shlomi Schwartz

Это связано с тем, что ng-include создает новую дочернюю область, поэтому $scope.lineText не изменяется. Я думаю, что this относится к текущей области видимости, поэтому следует установить this.lineText.

81
Renan Tomal Fernandes

Как уже упоминалось @Renan, ng-include создает новую дочернюю область. Эта область прототипически наследуется (см. Пунктирные линии ниже) от области видимости HomeCtrl. ng-model="lineText" фактически создает примитивное свойство области действия для дочерней области, а не области действия HomeCtrl. Эта дочерняя область недоступна для родительской области/HomeCtrl:

ng-include scope

Чтобы сохранить то, что пользователь ввел в массив $ scope.lines HomeCtrl, я предлагаю вам передать значение в функцию addLine:

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

Кроме того, поскольку lineText принадлежит области действия/частичному ngInclude, я считаю, что он должен нести ответственность за его очистку:

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

Функция addLine (), таким образом, станет:

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

Fiddle .

Альтернативы:

  • определите свойство объекта в $ scope HomeCtrl и используйте его в частичном: ng-model="someObj.lineText; скрипка
  • не рекомендуется, это скорее хак: используйте $ parent в частичном для создания/доступа к свойству lineText в области видимости HomeCtrl $: ng-model="$parent.lineText"; скрипка

Это немного объясняет, почему работают две вышеупомянутые альтернативы, но это полностью объясняется здесь: Каковы нюансы области действия прототипа/прототипического наследования в AngularJS?

Я не рекомендую использовать this в функции addLine (). Становится гораздо менее понятно, к какой области доступа или манипуляции обращаются.

257
Mark Rajcok

Вместо использования this, как предполагает принятый ответ, используйте вместо него $parent. Итак, в вашем partial1.html у вас будет:

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

Если вы хотите узнать больше о области действия в ng-include или других директивах, проверьте это: https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-include

32
ErwinGO

Я понял, как обойти эту проблему, не смешивая родительские данные и данные подобласти. Установите ng-if в элементе ng-include и установите для него переменную области видимости. Например :

<div ng-include="{{ template }}" ng-if="show"/>

В вашем контроллере, когда вы установили все необходимые данные в своей области действия, тогда установите show в true. ng-include в этот момент скопирует набор данных в вашей области и установит его в вашей области.

Эмпирическое правило заключается в том, чтобы уменьшить объем данных за пределами области действия, иначе у вас есть такая ситуация.

Максимум

3
wascou