Ответ 1
Это из-за ng-include
, который создает новый дочерний объект, поэтому $scope.lineText
не изменяется. Я думаю, что this
относится к текущей области, поэтому this.lineText
должен быть установлен.
У меня есть этот маршрут модуля:
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
, однако это вызывает вызов контроллера дважды. Что мне здесь не хватает?
Это из-за ng-include
, который создает новый дочерний объект, поэтому $scope.lineText
не изменяется. Я думаю, что this
относится к текущей области, поэтому this.lineText
должен быть установлен.
Как упоминал @Renan, ng-include создает новый дочерний объект. Эта область прототипа наследует (см. Пунктирные линии ниже) из области HomeCtrl. ng-model="lineText"
фактически создает примитивное свойство области в области дочернего объекта, а не область HomeCtrl. Эта область дочернего объекта недоступна для области родителя /HomeCtrl:
Чтобы сохранить то, что пользователь вводил в массив HomeCtrl $scope.lines, я предлагаю передать значение функции addLine:
<form ng-submit="addLine(lineText)">
Кроме того, поскольку lineText принадлежит области ngInclude/partial, я считаю, что он должен отвечать за ее очистку:
<form ng-submit="addLine(lineText); lineText=''">
Функция addLine() будет таким образом:
$scope.addLine = function(lineText) {
$scope.chat.addLine(lineText);
$scope.lines.push({
text: lineText
});
};
Альтернатива:
ng-model="someObj.lineText
; fiddlelineText
в области HomeCtrl $: ng-model="$parent.lineText"
; fiddleНемного нужно объяснить, почему работают эти две альтернативы, но здесь полностью объясняется: Каковы нюансы объема прототипного/прототипического наследования в AngularJS?
Я не рекомендую использовать this
в функции addLine(). Становится гораздо менее понятным, к какой области доступа обращаются/манипулируют.
Вместо использования 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
Я выяснил, как обойти эту проблему, не смешивая данные родительского и субсайта.
Установите ng-if
в элементе ng-include
и установите для него переменную области видимости.
Например:
<div ng-include="{{ template }}" ng-if="show"/>
В вашем контроллере, когда вы установили все данные, которые вам нужны, в подпунктовой области, установите show на true
. ng-include
скопирует в данный момент данные, установленные в вашей области действия, и установит их в вашей области видимости.
Эмпирическое правило состоит в том, чтобы уменьшить объем данных области, более глубоких, чем у вас есть.
Max