Ng- 모델은 컨트롤러 값을 업데이트하지 않습니다


270

아마도 어리석은 질문이지만 간단한 입력과 버튼으로 HTML 양식이 있습니다.

<input type="text" ng-model="searchText" />
<button ng-click="check()">Check!</button>
{{ searchText }}

그런 다음 컨트롤러에서 (템플릿 및 컨트롤러는 routeProvider에서 호출됩니다) :

$scope.check = function () {
    console.log($scope.searchText);
}

버튼을 클릭 할 때 콘솔에서보기가 올바르게 업데이트되었지만 정의되지 않은 이유는 무엇입니까?

감사!

업데이트 : 실제로이 문제를 해결 한 것처럼 보입니다 (일부 해결 방법이 필요합니다). 내 속성 이름을에서 (으) searchText로 변경 search.text한 다음 $scope.search = {};컨트롤러와 voila에 빈 객체 를 정의 해야했습니다 ... 왜 작동하는지 모르겠습니다. 그러나 ;]


문서의이 부분에서이 컨트롤러를 사용하고 있습니까? 최소한의 실패 사례를 게시 할 수 있습니까?
wroniasty

1
예, 100 % 컨트롤러가 정상인지 확인하십시오. 문제는 저에게 익숙한 것 같습니다 ... 놀랍게도 속성 이름을에서 (으) searchText로 변경하면 search.text왜 작동합니까 ??
연금술

4
@Arthur : 그것은 분명하지 않지만 ng-model은 뷰에서 일종의 말하기 로컬 변수 만 생성합니다. 이렇게 유지하려면 check () 함수에 전달해야합니다. searchText)와 컨트롤러가 인식합니다. 도움이
연금술

3
기록을 위해, 그것은 철자 voila가 아닌 vuala, wolla
댄 Bechard

3
당신이 찾고있는 대답은 stackoverflow.com/a/14049482/1217913
Willa

답변:


71

버전 별 컨트롤러 (권장)

여기 템플릿

<div ng-app="example" ng-controller="myController as $ctrl">
    <input type="text" ng-model="$ctrl.searchText" />
    <button ng-click="$ctrl.check()">Check!</button>
    {{ $ctrl.searchText }}
</div>

JS

angular.module('example', [])
  .controller('myController', function() {
    var vm = this;
    vm.check = function () {
      console.log(vm.searchText);
    };
  });

예 : http://codepen.io/Damax/pen/rjawoO

Angular 2.x 또는 Angular 1.5 이상에서 구성 요소를 사용하는 것이 가장 좋습니다.

########

옛날 방식 (권장하지 않음)

문자열은 원시적이므로 대신 객체를 사용하는 것이 좋습니다.

마크 업에서 이것을 시도하십시오

<input type="text" ng-model="searchText" />
<button ng-click="check(searchText)">Check!</button>
{{ searchText }}

그리고 이것은 컨트롤러에서

$scope.check = function (searchText) {
    console.log(searchText);
}

17
이것은 단방향으로 만 작동합니다 ... 값을 변경하려면 어떻게해야 searchText합니까?
cdmckay

199
이것은 또한 "왜?"라고 대답하지 않습니다. 질문.
cdmckay

4
버튼을 사용하지 않으려면 어떻게해야합니까? 예를 들어 enter에 제출해야합니다
danikoren

2
Saniko => enter를 제출하려면 양식 태그와 ng-submit을 사용해야 합니다 ( docs.angularjs.org/api/ng.directive:ngSubmit )
Damax

1
@ HP's411 문자열이 프리미티브이기 때문입니다. Angular가 값을 할당하면 포인터가 값으로 변경되므로 컨트롤러는 값에 대한 이전 포인터가 있으므로 이전 값을 찾습니다.
Damax

620

"ng-model을 사용한다면 거기에 점이 있어야합니다."
모델이 object.property를 가리 키도록하고 나면 좋을 것입니다.

제어 장치

$scope.formData = {};
$scope.check = function () {
  console.log($scope.formData.searchText.$modelValue); //works
}

주형

<input ng-model="formData.searchText"/>
<button ng-click="check()">Check!</button>

이는 자식 경로 나 ng-repeats와 같은 자식 범위가 재생 중일 때 발생합니다. 자식 범위는 자체 가치를 만들고 여기에 설명 된대로 이름 충돌이 발생 합니다 .

자세한 내용은이 비디오 클립을 참조하십시오 : https://www.youtube.com/watch?v=SBwoFkRjZvv&&


94
이것이 실제 답변입니다.
keslert 2016 년

16
@Catfish 프로토 타입 상속을 사용하면 자식 속성에 쓸 때마다 부모 속성에 대한 참조 / 연결이 더 이상 존재하지 않습니다. 점이없는 경우 Angular Scopes 모델 방식으로 하위 범위 내에 새로운 속성이 생성됩니다. 이 동영상에 대해 자세히 설명합니다 : youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=30m
Will Stern

1
그라시아 스 보스. 사실입니다! 그러나 Ionic 프레임 워크와 함께 사용할 때만 문제가 발생하므로 일관된 단점이 아닌 것 같습니다
Don Barry

6
@ user3677331 예를 들어 ng-repeat 내의 항목과 같이 자식 범위와 대화하려고 할 때까지 점없이 잘 작동합니다. 모델 이름이 "전화"라고 가정합니다. 하위 범위에 "전화"가 생성되면 하위 범위에 "전화"변수가 있으므로 상위 범위의 "전화"에 액세스 할 수 없으므로 범위 충돌이 발생합니다. 아이 범위가 user.phone를 생성하면 두 범위가 동일한 개체를 가리키는 때문에, 그것은 부모의 사용자 개체에 추가됩니다 반면
윌 스턴

3
매우 도움이됩니다. 나는 비교적 모호한 질문에 대한 답을 찾을 것이라고 확신하지 못했지만 이것은 끝났다.
CodeManiak

57

AngularJS를 사용한 웹 응용 프로그램 개발 책 p.19에서는 다음과 같이 작성되었습니다.

범위 속성에 직접 바인딩을 피하십시오. 범위에 노출 된 개체 속성에 대한 양방향 데이터 바인딩이 선호되는 접근 방식입니다. 경험상 ng-model 지시문에 제공된 표현식에 점이 있어야합니다 (예 : ng-model = "thing.name").

범위는 JavaScript 객체 일 뿐이며 dom 계층 구조를 모방합니다. JavaScript Prototype Inheritance 에 따르면 범위 속성은 범위를 통해 분리됩니다. 이를 피하려면 도트 표기법 을 사용하여 ng 모델을 바인딩해야합니다.


2
이 참조에 감사드립니다. 나는 이것이 ng-model과 관련된 흥미로운 점이라고 생각합니다.
Kings

44

작품 this대신 사용 $scope.

function AppCtrl($scope){
  $scope.searchText = "";
  $scope.check = function () {
    console.log("You typed '" + this.searchText + "'"); // used 'this' instead of $scope
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app>
  <div ng-controller="AppCtrl">
    <input ng-model="searchText"/>
    <button ng-click="check()">Write console log</button>
  </div>
</div>

편집 : 이 답변을 작성할 때 나는 이것보다 훨씬 복잡한 상황을 겪었습니다. 논평 후에, 나는 그것이 왜 효과가 있는지 이해하기 위해 그것을 재현하려고 노력했지만 운이 없다. 어떻게 든 새로운 이유가 생성되고 this그 범위를 참조한다고 생각합니다. 그러나 $scope사용되는 경우 실제로 Javascript의 어휘 범위 기능으로 인해 상위 $ scope를 나타냅니다 .

이 문제가있는 사람이 이런 식으로 테스트하고 알려 주면 좋을 것입니다.


완벽한, 당신은 천재입니다
fjcero

1
$scope새로운 범위 를 생성하기 위해 연결된 함수처럼 보입니다 (즉, function check()에서 this하위 범위 인 범위를 나타냅니다 $scope). 왜 그래야만하지? 설명 좀 해줄 래?
Xun Yang

1
이 경우 왜 '$ scope'대신 'this'를 사용해야합니까? 이전 프로젝트에서 $ scope를 사용하여 작동했지만 이번에는 $ scope를 사용하여 작동하지 않습니다. 그러나 '이것은 효과가 있습니다. 왜 그런 겁니까?
Rashedul.Rubel

이것은 작동하지만 말 this.searchText = "something else"하거나하더라도 $scope.searchText = "something else"보기를 업데이트하지 않습니다. 이 문제를 설명 할 수 있습니까?
Shri

해야한다. 위의 코드를 사용하여 시도했지만보기가 업데이트되었습니다.
Feyyaz

13

나는 같은 문제가 있었고 컨트롤러의 맨 앞에 빈 객체를 먼저 선언하지 않았기 때문입니다.

$scope.model = {}

<input ng-model="model.firstProperty">

이것이 당신을 위해 작동하기를 바랍니다!


10

사소한보기 (중첩 범위가 있음)를 처리 할 때 동일한 문제가 발생했습니다. 그리고 마침내 프로토 타입 기반의 자바 스크립트 상속 특성으로 인해 AngularJS 애플리케이션을 개발할 때 이것이 알려진 까다로운 일이라는 것을 발견했습니다. AngularJS 중첩 범위는이 메커니즘을 통해 생성됩니다. 그리고 ng-model에서 생성 된 값은 부모 범위 (컨트롤러에 주입 된 것일 수도 있음)에 값이 표시되지 않는다고 말하지 않고 자식 범위에 배치됩니다. 점을 사용하지 않으면 값이 부모 범위에 정의 된 동일한 이름을 가진 모든 속성을 음영 처리합니다 프로토 타입 참조 액세스를 시행합니다. 자세한 내용은이 문제를 설명하기위한 온라인 비디오 ( http://egghead.io/video/angularjs-the-dot/) 와 그 뒤의 설명을 확인하십시오.


6

이 바이올린을보십시오 http://jsfiddle.net/ganarajpr/MSjqL/

나는 당신이하고있는 일을 정확하게 수행했으며 작동하는 것 같습니다. 여기서 작동하지 않는 것을 확인할 수 있습니까?


흠 .. 이것에 대해 조사해 주셔서 감사합니다. 그리고 더 중요한 것은 왜 객체와 함께 작동하고 일반 문자열 변수와는 작동하지 않습니까? 아마도 routeProvider에서 컨트롤러를 부적절한 방식으로 참조하게 할 수 있습니까 ?? 전역을 피하고 내 컨트롤러를 modulename.ctrlName으로 controllers.js 파일에 넣었습니다. 두통을 일으킬 수 있습니까?
연금술

왜 그것이 당신에게 효과가 없는지 잘 모르겠습니다. 이 문제를 바이올린으로 격리 할 수 ​​있다면 누군가가 더 나은 답변을 줄 수있을 것 같습니다.)
ganaraj

좋아, 할거야, 지금 일을 끝내고 있지만 내일 또는 나중에 저녁에 그렇게 할 것입니다. 내 ctrl의 네임 스페이스를 지정하는 방식에 문제가있을 수 있습니다.
연금술

6

아무도 이것을 언급하지 않았으므로 $parent바인딩 된 속성 에 추가하여 문제를 해결할 수 있습니다

<div ng-controller="LoginController">
    <input type="text" name="login" class="form-control" ng-model="$parent.ssn" ng-pattern="/\d{6,8}-\d{4}|\d{10,12}/" ng-required="true" />
    <button class="button-big" type="submit" ng-click="BankLogin()" ng-disabled="!bankidForm.login.$valid">Logga in</button>
</div>

그리고 컨트롤러

app.controller("LoginController", ['$scope', function ($scope) {
    $scope.ssn = '';

    $scope.BankLogin = function () {
        console.log($scope.ssn); // works!
    };
}]);

답변 주셔서 감사합니다,하지만 y 작동합니까? 부모가 아닌 동일한 범위 요소에서 이상적으로 작업해야합니까?
V31

5

나를 위해 문제를 해결하기 위해 내 데이터를 개체 (여기서는 "데이터")에 저장했습니다.

NgApp.controller('MyController', function($scope) {

   $scope.my_title = ""; // This don't work in ng-click function called

   $scope.datas = {
      'my_title' : "",
   };

   $scope.doAction = function() {
         console.log($scope.my_title); // bad value
         console.log($scope.datas.my_title); // Good Value binded by'ng-model'
   }
   

});

도움이 될 것입니다.


3
여기에 주제 오프 약간 있지만, '데이터'는 '자료'에 대한 복수의 용어입니다
thethakuri

헝가리어로 @thethakuri와 "datum"은 "날짜"이므로 다음 중 어느 것도 사용하지 않을 것입니다. : P
EpicPandaForce

나는 와플 하우스를 IHOP보다 선호합니다
Nico Westerdale

2

방금 body-element에 바인딩 된 root_controller를 사용 하여이 문제가 발생했습니다. 그런 다음 각도 라우터와 함께 ng-view를 사용하고있었습니다. 문제는 각도가 항상 ng-view 요소에 html을 삽입 할 때 새로운 범위를 만듭니다. 결과적으로, "확인"기능은 ng-model 요소에 의해 수정 된 범위의 상위 범위에서 정의되었습니다.

문제를 해결하려면 라우트로드 된 html 컨텐츠 내에 전용 컨트롤러를 사용하십시오.


2

ng-keypress입력 텍스트 입력 및 ng-click아이콘 검색을 활성화하려면 다음을 수행 하십시오 .

<input type="text" ng-model="searchText" ng-keypress="keyEnter(this,$event)" />
<button ng-click="check(searchText)">Check!</button>

in the controller
$scope.search = function (searchText) {
        console.log(searchText);
    }
    $scope.keyEnter = function (serachText,$event) {
        var keyCode = $event.which || $event.keyCode;
        if (keyCode === 13) {//KeyCode for Enter key
           console.log(searchText);
        }
    }

2

나는 같은 문제가 있었다.
올바른 방법은 'searchText'를 객체 내부의 속성으로 설정하는 것입니다.

그러나 문자열을 그대로 두려면 어떻게해야합니까? 글쎄, 나는 여기에 언급 된 모든 단일 방법을 시도했지만 아무것도 효과가 없었습니다.
그러나 나는 문제가 시작에 불과하다는 것을 알았으므로 value 속성을 설정했는데 효과가있었습니다.

<input type="text" ng-model="searchText" value={{searchText}} />

이 방법으로 값은 '$ scope.searchText'값으로 설정되며 입력 값이 변경 될 때 업데이트됩니다.

나는 그것이 해결 방법이라는 것을 알고 있지만 그것은 나를 위해 일했다 ..


2

나는 같은 문제에 직면했다 ... 나를 위해 일한 해결책은이 키워드를 사용하는 것입니다 ..........

alert (this.ModelName);

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.