ng-include를 사용할 때 범위 상실


181

이 모듈 경로가 있습니다.

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.lineTextundefined에 추가 ng-controller="HomeCtrl"하여 해결할 수 partial1.html있지만 컨트롤러가 두 번 호출됩니다. 내가 여기서 무엇을 놓치고 있습니까?

답변:


83

이것은 ng-include새로운 자식 범위를 생성 하기 때문에 $scope.lineText변경되지 않습니다. 나는 그것이 this현재 범위 를 참조 한다고 생각 하므로 this.lineText설정해야합니다.


260

@Renan이 언급했듯이 ng-include는 새로운 자식 범위를 만듭니다. 이 범위는 HomeCtrl 범위에서 프로토 타입으로 상속됩니다 (아래 점선 참조). ng-model="lineText"실제로 HomeCtrl의 범위가 아닌 자식 범위에 기본 범위 속성을 만듭니다. 이 하위 범위는 부모 / HomeCtrl 범위에서 액세스 할 수 없습니다.

ng- 포함 범위

사용자가 HomeCtrl의 $ scope.lines 배열에 입력 한 내용을 저장하려면 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
    });
};

바이올린 .

대안 :

  • HomeCtrl의 $ scope에서 객체 속성을 정의하고 부분적으로 사용하십시오 ng-model="someObj.lineText.; 깡깡이
  • 권장하지 않습니다. 이것은 더 많은 해킹입니다. 부분적으로 $ parent를 사용 lineText하여 HomeCtrl $ scope 에서 속성   을 만들거나 액세스합니다 ng-model="$parent.lineText". 깡깡이

위의 두 가지 대안이 작동하는 이유를 설명하는 데 약간 관여하지만 AngularJS에서 스코프 프로토 타입 / 프로토 타입 상속의 뉘앙스는 무엇입니까?

thisaddLine () 함수를 사용하지 않는 것이 좋습니다 . 어느 스코프가 액세스 / 조작되는지 명확하지 않습니다.


1
마침내 이해합니다.
Scott Tesler

1
같은 질문 @Jess는 왜 이것이 핵으로 간주됩니까?
qbert65536

13
@ qbert65536, 그것은 본질적으로 해킹 / 취약성입니다. HTML을 재구성하면 더 이상 작동하지 않을 수 있기 때문입니다. 예를 들어, 작동하려면이를 사용해야 할 수도 있습니다 $parent.$parent.... 다른 방법으로 $parentDOM 구조에 대한 가정을 사용 하십시오.
Mark Rajcok

6
위의 @Jess '링크가이 범위 이해 ngInclude 로 변경되었습니다 . 전체 페이지를 읽으십시오. 훌륭합니다.
mraaroncruz

1
이것은 훌륭한 세부 답변이지만 모든 성공을 거두지 못했습니다. 컨트롤러에 대한 입력이있는 양식이 있으며 컨트롤러의 결과를 다른 div에서 볼 수 있습니다. 입력을 입력하면 동기화가 손실되고 앱이 실행되는 동안 view div에서 상수 0.00 값이 유지됩니다.
zahra

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>

범위 ng-include또는 다른 지시문 에 대한 자세한 내용은 https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-include를 참조하십시오.


1
모든 독자에게 그는 각도 $scope.$parent대신에 $parent정의되지 않은 것을 의미 합니다 .
Sebastialonso

1
이 대답은 나를 위해 하루를 저장합니다! $ parent 사용을 지적 해 주셔서 감사합니다.
Derek Webb

$ scope. $ parent가 참조로 전달됩니까? 아니면 부모님의 사본입니까?
OMGPOP

1
@Sebastiallonso가 잘못되었습니다. $ scope. $ parent.lineText가 정의되지 않았습니다. $ parent.lineText가 작동 중입니다. this.lineText 또는 단순히 lineText도 작동 중입니다.
OMGPOP

그것은 $scope.$parent각도 1.3.20에서 나를 위해 작동합니다
radtek

4

부모와 하위 범위 데이터를 혼합하지 않고이 문제를 해결하는 방법을 알아 냈습니다. 요소 ng-if에 a 를 ng-include설정하고 범위 변수로 설정하십시오. 예를 들면 다음과 같습니다.

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

컨트롤러에서 하위 범위에 필요한 모든 데이터를 설정 한 후 show를로 설정하십시오 true. 그만큼ng-include 현재 범위에서 설정 한 데이터를 복사하여 하위 범위에서 설정합니다.

경험상 스코프 데이터가 스코프 범위를 더 깊게 줄이려면 그렇지 않으면이 상황이 발생합니다.

맥스


비슷한 문제 에이 방법을 사용하고 있지만 모든 경우에 적합한 것은 아닙니다. 당신은 포함 된 요소가 ... 숨겨진 만나지 할 특히 때
iSpithash
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.