Ng-model nie aktualizuje wartości kontrolera

Prawdopodobnie głupie pytanie, ale mam swój formularz html z prostym wejściem i przyciskiem:

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

Następnie w kontrolerze (szablon i kontroler są wywoływane z routeProvider):

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

Dlaczego widok jest zaktualizowany poprawnie, ale niezdefiniowany w konsoli po kliknięciu przycisku?

Dzięki!

Update: Wygląda na to, że faktycznie rozwiązałem ten problem (wcześniej musiałem wymyślić pewne obejścia) z: Musiałem tylko zmienić nazwę mojej nieruchomości z searchText na search.text, wtedy zdefiniuj pusty obiekt $scope.search = {}; w kontrolerze i voila... Nie mam pojęcia dlaczego to działa;]

Author: Damjan Pavlica, 2012-09-27

13 answers

Kontroler w wersji (zalecane)

Tutaj szablon

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

Przykład: http://codepen.io/Damax/pen/rjawoO

Najlepiej będzie użyć komponentu z Angular 2.x lub kątowe 1.5 lub górne

########

Old way (NOT recommended)

Nie jest to zalecane, ponieważ ciąg znaków jest prymitywnym, wysoce zalecanym do używania obiektu zamiast

Spróbuj tego w znacznikach

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

Oraz to w Twoim kontrolerze

$scope.check = function (searchText) {
    console.log(searchText);
}
 64
Author: Damax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-05 09:17:54

"Jeśli używasz ng-model, musisz mieć tam kropkę."
Niech twój model wskaże obiekt.własność i będziesz gotowy do drogi.

Controller

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

Szablon

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

Dzieje się tak, gdy zakresy dziecięce są w play - like child routes lub ng-repeats. Child-scope tworzy własną wartość i rodzi się konflikt nazw , Jak pokazano tutaj:

Zobacz ten klip wideo, aby dowiedzieć się więcej: https://www.youtube.com/watch?v=SBwoFkRjZvE&t=3m15s

 579
Author: Will Stern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-30 19:57:36

W masteringu tworzenia aplikacji internetowych z AngularJS book P. 19, napisano, że

Unikaj bezpośredniego powiązania z właściwościami scope. Dwukierunkowe powiązanie danych z właściwości obiektu (narażone na zakres) są preferowanym podejściem. Jako zasada kciuka, należy mieć kropkę w wyrażeniu dostarczonym do dyrektywa ng-model (np. ng-model="thing.name").

Zakresy są tylko obiektami JavaScript i naśladują hierarchię dom. Zgodnie z JavaScript Dziedziczenie prototypu , właściwości zakresów są rozdzielane przez zakresy. Aby tego uniknąć, notacja kropkowa powinna być używana do wiązania modeli ng.

 55
Author: efirat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-20 15:23:27

Użycie this zamiast $scope działa.

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>

Edit: w czasie pisania tej odpowiedzi, miałem znacznie bardziej skomplikowaną sytuację niż ta. Po komentarzach próbowałem go odtworzyć, aby zrozumieć, dlaczego działa, ale bez powodzenia. Myślę, że w jakiś sposób (nie wiem dlaczego) generowany jest nowy zakres potomny i this odnosi się do tego zakresu. Ale jeśli $scope jest używane, to w rzeczywistości odnosi się do rodzica $scope ze względu na zakres leksykalny javascript cecha.

Byłoby świetnie, gdyby ktoś z tym problemem testował w ten sposób i nas informował.

 39
Author: Feyyaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:49

Miałem ten sam problem i było to spowodowane tym, że nie zadeklarowałem pustego obiektu najpierw na górze kontrolera:

$scope.model = {}

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

Mam nadzieję, że to zadziała dla Ciebie!

 10
Author: Millsionaire,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-15 11:59:23

Natknąłem się na ten sam problem, gdy miałem do czynienia z nietrywialnym widokiem(są zagnieżdżone zakresy). I wreszcie odkrył, że jest to znana trudna rzecz przy opracowywaniu aplikacji AngularJS ze względu na naturę dziedziczenia opartego na prototypach java-script. Za pomocą tego mechanizmu tworzone są zagnieżdżone lunety AngularJS. A wartość utworzona z ng-model jest umieszczana w zakresie potomnym, nie mówiąc, że zakres rodzica (może ten wtryskiwany do kontrolera) nie będzie widział wartości, wartość będzie również zaciemniać dowolny właściwość o tej samej nazwie zdefiniowana w zakresie nadrzędnym, jeśli nie używa kropki do wymuszenia dostępu do referencji prototypu. Aby uzyskać więcej szczegółów, sprawdź wideo online, aby zilustrować ten problem, http://egghead.io/video/angularjs-the-dot / i komentarze.

 9
Author: Roger Jin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-03 02:04:22

Spójrz na to skrzypce http://jsfiddle.net/ganarajpr/MSjqL/

Mam ( zakładam! ) zrobił dokładnie to, co robiłeś i wydaje się, że działa. Możesz sprawdzić, co nie działa tutaj dla Ciebie?

 5
Author: ganaraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-27 11:12:39

Dla mnie problem został rozwiązany poprzez umieszczenie moich danych w obiekcie (tutaj "dane").

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'
   }
   

});

I Hop it will help

 4
Author: Plici Stéphane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-21 15:24:18

Ponieważ nikt o tym nie wspomniał, problem można rozwiązać dodając $parent do właściwości

<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>

I kontroler

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

    $scope.BankLogin = function () {
        console.log($scope.ssn); // works!
    };
}]);
 3
Author: Eric Herlitz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-18 13:22:15

Miałem właśnie ten problem z użyciem root_controllera związanego z elementem ciała. Następnie używałem ng-view z routerem kątowym. Problem polega na tym, że angular zawsze tworzy nowy zakres, gdy wstawia html do elementu ng-view. W konsekwencji, moja funkcja "check" została zdefiniowana na nadrzędnym zakresie zakresu, który został zmodyfikowany przez mój element modelu ng.

Aby rozwiązać problem, wystarczy użyć dedykowanego kontrolera w treści html załadowanej trasą.

 1
Author: moritz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-13 07:12:42

Możesz to zrobić, aby włączyć wyszukiwanie w ng-keypress Wprowadź tekst wejściowy i w ng-click ikonę:

<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);
        }
    }
 1
Author: Naoufal Gaffa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-04 09:50:06

Miałem ten sam problem.
Właściwym sposobem byłoby ustawienie' searchText ' jako właściwości wewnątrz obiektu.

Ale co, jeśli chcę zostawić to tak, jak jest, ciąg? próbowałem każdej wymienionej metody, nic nie działało.
Ale potem zauważyłem, że problem jest tylko w inicjacji, więc po prostu ustawić atrybut wartości i to działa.

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

W ten sposób wartość jest ustawiona na ' $ scope.wartość searchText i jest aktualizowana, gdy wartość wejściowa zmiany.

Wiem, że to obejście, ale mi się udało..
 1
Author: Hike Nalbandyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-15 13:31:41

Miałem ten sam problem... Rozdzielczość, która zadziałała dla mnie, to użycie tego słowa kluczowego..........

Alert (this.ModelName);

 1
Author: SnktJavaMaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-30 08:57:51