2013-06-02 16 views
10

Próbuję zwrócić pojedynczy rekord z obietnicy w AngularJs (1.0.7) i powiązać wynik z formularzem. Formularz jest poprawnie powiązany, ale pola wejściowe są tylko do odczytu - nie mogę edytować wartości.

Jeśli zamiast tego zawijam rekord w tablicy i iteruję za pomocą polecenia ng: repeat, formularz jest poprawnie powiązany i mogę edytować wartości.

Utworzyłem plnkr który demonstruje kwestię jasno:

http://embed.plnkr.co/fOWyhVUfekRbKUSRf7ut/preview

można edytować bezpośrednio związany i list związany pól wejściowych, jednak pole związany z pojedynczym obietnicy nie może być edytowany.

Czy można powiązać ng: model bezpośrednio z obiektem zwróconym przez obietnicę, czy też muszę użyć tablicy, aby to zadziałało?

app.controller('MainCtrl', function($scope, $timeout, $q) { 

    var person = {"name": "Bill Gates"} 

    var deferList = $q.defer(); 
    var deferSingle = $q.defer(); 

    // Bind the person object directly to the scope. This is editable. 
    $scope.direct = person;  

    // Bind a promise to the scope that will return a list of people. This is editable. 
    $scope.list = deferList.promise; 

    // Bind ap romise to the scope that will return a single person record. This is *not* editable. 
    $scope.single = deferSingle.promise; 

    // Resolve the promises 
    $timeout(function(){ 
    deferList.resolve([person]); // Array 
    deferSingle.resolve(person); // Just the record itself 
    }, 100); 


}); 


<body ng-controller="MainCtrl"> 
    Directly Bound - This field is editable 
     <input ng:model="direct.name"/> 
    <hr/> 
    Singleton Promise - This field is *not* editable. 
     <input ng:model="single.name"/>  
    <hr/> 
    List Promise: - This field is editable 
     <div ng:repeat="person in list"> 
      <input ng:model="person.name"/> 
     </div> 

</body> 

Edit: Po pewnym debugowania, Znalazłem, że ng: dyrektywa model jest czytanie od wartości („$$ v”) składnik obietnicy, ale pisząc bezpośrednio do obietnicy sam obiekt.

Przy próbie edycji obietnicy, ViewModel powraca do pierwotnej wartości, zachowując znaki w samej obietnicy. Tak więc jeśli użytkownik wpisze "asdf" do pola wejściowego, wynik będzie następujący.

{Name: "Asdf", $$v: {Name: "Bill Gates"}} 

Zważywszy powinniśmy zamiast oczekiwać

{$$v: {Name: "asdf"}} 

Czy robię coś źle, czy też jest to potencjalnie błąd w angularjs?

(w celu dalszego wyjaśnienia, problem polega różnica w działaniu pomiędzy tablicą i obiektu zwróconej obietnicą. Bezpośrednie Wiązanie to jest jako próbka kontrolna),

+0

znalazłem problem i stworzyły żądania ciągnąć. https://github.com/angular/angular.js/pull/2854 –

Odpowiedz

8

UPDATE

Wydaje się, że problem został wprowadzony z AngularJS 1.0.3: http://jsfiddle.net/sonicsage/k8W4Y/6/

Jeśli przejdziesz na AngularJS 1.0.2, to zadziała.

Jest kwestią otwartą na GitHub: https://github.com/angular/angular.js/issues/1827

Oryginalny wątek na Google Groups.

Jest też ciekawy wątek o automatyczne rozpakowanie tutaj: https://github.com/angular/angular.js/pull/1676


Poprzez debugowanie aplikacji w konsoli Chrome, można zobaczyć, że single jest funkcją (obietnica):

> $('body.ng-scope').data('$scope').single 
Object {then: function, $$v: Object} 
$$v: Object 
then: function (b,g){var j=e(),h= 
__proto__: Object 

Podczas gdy direct to obiekt:

> $('body.ng-scope').data('$scope').direct 
Object {name: "Bill Gates", $$hashKey: "004"} 

Jednak naciśnięcie klawiszy na wejściu tylko do odczytu ma wpływ na promise, na przykład, wybierając cały tekst i skasowaniu go, choć nie ma wpływu na interfejsie użytkownika, ma wpływ na miejscu:

można dodatkowo debugować aplikację tutaj: http://run.plnkr.co/plunks/rDo7bFZlBq4rRH2ZNJn1/

EDIT

IMO bezpośrednio wiążąca obietnica polu nie jest obsługiwana (jest to oficjalnie udokumentowane?), zmiany kodu jako fol upadki zadziała:

// Bind ap romise to the scope that will return a single person record. This is *not* editable. 
    deferSingle.promise.then(function(data) { 
     $scope.single = data; 
    }, function(data) { 
     // error 
    }); 

Oto plunker: http://run.plnkr.co/plunks/rDo7bFZlBq4rRH2ZNJn1/

+0

oops, widziałem twoją edycję po tym, jak napisałem swoją odpowiedź. Nie jestem pewien, czy to błąd AngularJS. –

+0

Dzięki. Nie jestem w 100% pewien co do wiążącej rzeczy, która jest obsługiwana - działa jednak poprawnie prawie we wszystkich przypadkach, a w pliku parse.js jest specjalny kod do obsługi rozpakowywania $$ v. –

+0

Oczywiście bezpośrednie wiążące działa, jednak rzeczą szczególną jest to, że obietnica zwracająca "Array" działa, ale obietnica zwracająca słownik nie. Bezpośrednie powiązanie zostało po prostu dodane jako kontrola. –

Powiązane problemy