使用ng时丢失范围。

时间:2022-08-25 23:53:37

I have this module routes:

我有这个模块路线:

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'});
}]);

Home HTML:

HTML:

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

partial1 HTML:

partial1 HTML:

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

HomeCtrl:

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

In the addLine function $scope.lineText is undefined, this can be resolved by adding ng-controller="HomeCtrl" to partial1.html, however it causes the controller to be called twice. What am I missing here?

在addLine函数$scope中。lineText没有定义,可以通过向partial1添加ng-controller=“HomeCtrl”来解决。然而,它会使控制器被调用两次。我错过了什么?

4 个解决方案

#1


78  

This is because of ng-include which creates a new child scope, so $scope.lineText isn’t changed. I think that this refers to the current scope, so this.lineText should be set.

这是因为ng-include创建了一个新的子范围,即$scope。lineText并不改变。我认为这是指当前的范围,所以这个。lineText应该设置。

#2


249  

As @Renan mentioned, ng-include creates a new child scope. This scope prototypically inherits (see dashed lines below) from the HomeCtrl scope. ng-model="lineText" actually creates a primitive scope property on the child scope, not HomeCtrl's scope. This child scope is not accessible to the parent/HomeCtrl scope:

正如@Renan提到的,ng-include创建了一个新的子范围。这个范围原型从HomeCtrl范围继承(参见下面的虚线)。ng-model="lineText"实际上在子作用域上创建一个基本作用域属性,而不是HomeCtrl的作用域。父/HomeCtrl范围不能访问该子范围:

使用ng时丢失范围。

To store what the user typed into HomeCtrl's $scope.lines array, I suggest you pass the value to the addLine function:

将用户输入的内容存储到HomeCtrl的$scope中。行数组,我建议您将值传递给addLine函数:

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

In addition, since lineText is owned by the ngInclude scope/partial, I feel it should be responsible for clearing it:

此外,由于lineText为ngInclude范围/部分所有,我认为它应该负责清理它:

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

Function addLine() would thus become:

函数addLine()将会变成:

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

Fiddle.

小提琴。

Alternatives:

选择:

  • define an object property on HomeCtrl's $scope, and use that in the partial: ng-model="someObj.lineText; fiddle
  • 在HomeCtrl的$scope上定义一个对象属性,并在part: ng-model=" someobject . linetext;小提琴
  • not recommended, this is more of a hack: use $parent in the partial to create/access a lineText property on the HomeCtrl $scope:  ng-model="$parent.lineText"; fiddle
  • 不推荐,这更像是一种技巧:在部分中使用$parent在HomeCtrl $scope上创建/访问lineText属性:ng-model=“$parent.lineText”;小提琴

It is a bit involved to explain why the above two alternatives work, but it is fully explained here: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

解释上述两种替代方案的工作原理是有一定意义的,但它在这里得到了充分的解释:在AngularJS中,范围原型/原型继承的细微差别是什么?

I don't recommend using this in the addLine() function. It becomes much less clear which scope is being accessed/manipulated.

我不建议在addLine()函数中使用它。访问/操作哪个范围就不那么清楚了。

#3


29  

Instead of using this as the accepted answer suggests, use $parent instead. So in your partial1.htmlyou'll have:

与其像公认的答案那样使用它,不如使用$parent。所以在你partial1。htmlyou会:

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

If you want to learn more about the scope in ng-include or other directives, check this out: https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-include

如果您想了解更多关于ng-include或其他指示中的作用域的信息,请查看以下内容:https://github.com/angular/angular.js/wiki/understand - scope #ng-include

#4


3  

I've figured out how to work around this issue without mixing parent and sub scope data. Set a ng-if on the the ng-include element and set it to a scope variable. For example :

我已经知道如何在不混合父范围和子范围数据的情况下解决这个问题。在ng-include元素上设置一个ng,并将其设置为范围变量。例如:

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

In your controller, when you have set all the data you need in your sub scope, then set show to true. The ng-include will copy at this moment the data set in your scope and set it in your sub scope.

在您的控制器中,当您在子范围内设置所有需要的数据时,将显示为true。ng-include将在此时复制您的范围内的数据集,并将其设置在子范围内。

The rule of thumb is to reduce scope data deeper the scope are, else you have this situation.

经验法则是将范围数据缩小得更深,否则就会出现这种情况。

Max

马克斯

#1


78  

This is because of ng-include which creates a new child scope, so $scope.lineText isn’t changed. I think that this refers to the current scope, so this.lineText should be set.

这是因为ng-include创建了一个新的子范围,即$scope。lineText并不改变。我认为这是指当前的范围,所以这个。lineText应该设置。

#2


249  

As @Renan mentioned, ng-include creates a new child scope. This scope prototypically inherits (see dashed lines below) from the HomeCtrl scope. ng-model="lineText" actually creates a primitive scope property on the child scope, not HomeCtrl's scope. This child scope is not accessible to the parent/HomeCtrl scope:

正如@Renan提到的,ng-include创建了一个新的子范围。这个范围原型从HomeCtrl范围继承(参见下面的虚线)。ng-model="lineText"实际上在子作用域上创建一个基本作用域属性,而不是HomeCtrl的作用域。父/HomeCtrl范围不能访问该子范围:

使用ng时丢失范围。

To store what the user typed into HomeCtrl's $scope.lines array, I suggest you pass the value to the addLine function:

将用户输入的内容存储到HomeCtrl的$scope中。行数组,我建议您将值传递给addLine函数:

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

In addition, since lineText is owned by the ngInclude scope/partial, I feel it should be responsible for clearing it:

此外,由于lineText为ngInclude范围/部分所有,我认为它应该负责清理它:

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

Function addLine() would thus become:

函数addLine()将会变成:

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

Fiddle.

小提琴。

Alternatives:

选择:

  • define an object property on HomeCtrl's $scope, and use that in the partial: ng-model="someObj.lineText; fiddle
  • 在HomeCtrl的$scope上定义一个对象属性,并在part: ng-model=" someobject . linetext;小提琴
  • not recommended, this is more of a hack: use $parent in the partial to create/access a lineText property on the HomeCtrl $scope:  ng-model="$parent.lineText"; fiddle
  • 不推荐,这更像是一种技巧:在部分中使用$parent在HomeCtrl $scope上创建/访问lineText属性:ng-model=“$parent.lineText”;小提琴

It is a bit involved to explain why the above two alternatives work, but it is fully explained here: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

解释上述两种替代方案的工作原理是有一定意义的,但它在这里得到了充分的解释:在AngularJS中,范围原型/原型继承的细微差别是什么?

I don't recommend using this in the addLine() function. It becomes much less clear which scope is being accessed/manipulated.

我不建议在addLine()函数中使用它。访问/操作哪个范围就不那么清楚了。

#3


29  

Instead of using this as the accepted answer suggests, use $parent instead. So in your partial1.htmlyou'll have:

与其像公认的答案那样使用它,不如使用$parent。所以在你partial1。htmlyou会:

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

If you want to learn more about the scope in ng-include or other directives, check this out: https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-include

如果您想了解更多关于ng-include或其他指示中的作用域的信息,请查看以下内容:https://github.com/angular/angular.js/wiki/understand - scope #ng-include

#4


3  

I've figured out how to work around this issue without mixing parent and sub scope data. Set a ng-if on the the ng-include element and set it to a scope variable. For example :

我已经知道如何在不混合父范围和子范围数据的情况下解决这个问题。在ng-include元素上设置一个ng,并将其设置为范围变量。例如:

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

In your controller, when you have set all the data you need in your sub scope, then set show to true. The ng-include will copy at this moment the data set in your scope and set it in your sub scope.

在您的控制器中,当您在子范围内设置所有需要的数据时,将显示为true。ng-include将在此时复制您的范围内的数据集,并将其设置在子范围内。

The rule of thumb is to reduce scope data deeper the scope are, else you have this situation.

经验法则是将范围数据缩小得更深,否则就会出现这种情况。

Max

马克斯