使用ng-include时失去范围

Shl*_*rtz 180 html javascript angularjs angularjs-scope angularjs-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'});
}]);
Run Code Online (Sandbox Code Playgroud)

主页HTML:

<div ng-include src="views.partial1"></div>
Run Code Online (Sandbox Code Playgroud)

partial1 HTML:

<form ng-submit="addLine()">
    <input type="text" ng-model="lineText" size="30" placeholder="Type your message here">
</form>
Run Code Online (Sandbox Code Playgroud)

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 = "";
    };
...
}
Run Code Online (Sandbox Code Playgroud)

addLine函数$scope.lineTextundefined,这可以通过添加ng-controller="HomeCtrl"来解决partial1.html,但是它会导致控制器被调用两次.我在这里错过了什么?

Mar*_*cok 258

正如@Renan所提​​到的,ng-include创建了一个新的子范围.此范围从HomeCtrl范围原型继承(参见下面的虚线). ng-model="lineText"实际上在子范围上创建了一个原始范围属性,而不是HomeCtrl的范围.父/ HomeCtrl范围无法访问此子范围:

ng-include范围

要存储用户键入HomeCtrl的$ scope.lines数组的内容,我建议您将值传递给addLine函数:

 <form ng-submit="addLine(lineText)">
Run Code Online (Sandbox Code Playgroud)

另外,由于lineText归ngInclude范围/部分所有,我觉得应该负责清除它:

 <form ng-submit="addLine(lineText); lineText=''">
Run Code Online (Sandbox Code Playgroud)

函数addLine()因此将变为:

$scope.addLine = function(lineText) {
    $scope.chat.addLine(lineText);
    $scope.lines.push({
        text: lineText
    });
};
Run Code Online (Sandbox Code Playgroud)

小提琴.

备择方案:

  • 定义上HomeCtrl的$范围的对象属性,并使用在部分:ng-model="someObj.lineText; 小提琴
  • 不推荐,这更像是一个hack:在partial中使用$ parent来创建/访问lineTextHomeCtrl $ scope上的属性:   ng-model="$parent.lineText"; 小提琴

有一点涉及到解释为什么上述两个替代方案有效,但这里有充分的解释:AngularJS中范围原型/原型继承的细微差别是什么?

我不建议this在addLine()函数中使用.对于访问/操纵哪个范围变得不太清楚.

  • @ qbert65536,它本质上是一个hack/fragile,因为如果重构HTML,它可能不再起作用了.例如,您可能需要使用`$ parent.$ parent ...`来使其工作.换句话说,使用`$ parent`对DOM结构做出假设. (13认同)
  • 上面的@Jess'链接已更改为__ [Understanding Scopes ngInclude](https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-include)__.阅读整页,很棒. (6认同)

Ren*_*des 82

这是因为ng-include它创建了一个新的子范围,因此$scope.lineText不会更改.我认为这this是指当前的范围,所以this.lineText应该设置.


Erw*_*nGO 33

而不是使用this已接受的答案建议,$parent而是使用.所以,partial1.html你将拥有:

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

如果您想进一步了解范围ng-include或其他指令,请查看:https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-include