使用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
来partial1.html
,但它会导致控制器被调用两次。 我在这里错过了什么?
这是因为ng-include
创build了一个新的子范围,所以$scope.lineText
不会被改变。 我认为this
是指当前范围,所以应该设置this.lineText
。
正如@Renan提到的,ng-include创build一个新的子范围。 这个范围从HomeCtrl范围原型inheritance(见下面的虚线)。 ng-model="lineText"
实际上是在子作用域上创build一个基本的作用域属性,而不是HomeCtrl的作用域。 父级/ HomeCtrl范围无法访问此子范围:
要存储用户input到HomeCtrl的$ scope.lines数组,我build议你将值传递给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 }); };
小提琴 。
备择scheme:
- 在HomeCtrl的$ scope上定义一个对象属性,并在partial:
ng-model="someObj.lineText
; fiddle - 不推荐,这是更多的黑客:在部分中使用$父母来创build/访问
lineText
上的lineText属性$ scope:ng-model="$parent.lineText"
; 小提琴
解释为什么上述两种方法有效,有点牵扯,但是这里充分说明了: AngularJS中范围原型/原型inheritance的细微差别是什么?
我不build议在addLine()函数中使用它。 它变得更不清楚哪个范围被访问/操纵。
而不是使用this
接受的答案build议,而是使用$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-include
元素上设置一个ng-if
,并将其设置为一个范围variables。 例如 :
<div ng-include="{{ template }}" ng-if="show"/>
在您的控制器中,当您在子范围中设置了所有需要的数据时,将show设置为true
。 ng-include
将在这个时候复制你的作用域中的数据集并将其设置在你的子作用域中。
经验法则是将范围数据的范围缩小,否则就会出现这种情况。
马克斯