Подтвердить что ты не робот

AngularJS - ng: model - Поле всегда доступно, когда привязано к $q?

Я пытаюсь вернуть одну запись из обещания в AngularJs (1.0.7) и привязать результат к форме. Форма правильно связывается, однако поля ввода доступны только для чтения - я не могу редактировать значения.

Если вместо этого я переношу запись в массив и повторяю с помощью ng: repeat, форма связывается правильно, и я могу редактировать значения.

Я создал plnkr, который ясно показывает проблему:

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

Вы можете редактировать поля с привязкой непосредственно связанных и связанных списков, однако поле, связанное с единственным обещанием, невозможно отредактировать.

Можно ли привязать ng: model непосредственно к объекту, возвращенному из обещания, или мне нужно использовать массив, чтобы заставить это работать?

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>

Изменить. После некоторой отладки я обнаружил, что директива ng: model читает из компонента ($$ v ') обещания, но прямо пишет объект обещания сам по себе.

При попытке отредактировать обещание, ViewModel продолжает возвращаться к исходному значению, сохраняя символы в самом обещании. Таким образом, если пользователь вводит "asdf" в поле ввода, результат будет следующим.

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

В то время как мы должны ожидать

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

Я делаю что-то неправильно или это потенциально ошибка в AngularJS?

(Чтобы уточнить, проблема заключается в различии в поведении между массивом и объектом, возвращенным обещанием. Прямое связывание просто существует как элемент управления)

4b9b3361

Ответ 1

UPDATE

Кажется, что проблема была введена с помощью AngularJS 1.0.3:  http://jsfiddle.net/sonicsage/k8W4Y/6/

Если вы переключитесь на AngularJS 1.0.2, он будет работать.

В GitHub есть открытая проблема: https://github.com/angular/angular.js/issues/1827

Оригинальная тема на Группах Google.

Здесь также есть интересная тема об автоматическом разворачивании:  https://github.com/angular/angular.js/pull/1676


Отлаживая приложение в консоли Chrome, вы можете видеть, что single - это функция (обещание):

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

Пока direct является объектом:

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

Однако нажатие клавиш на входе только для чтения влияет на promise, например, выбирая весь текст и стирая его, хотя и не влияет на пользовательский интерфейс, оказывает влияние на свойство:

> $('body.ng-scope').data('$scope').single.name
""

Вы также можете отладить приложение здесь: http://run.plnkr.co/plunks/rDo7bFZlBq4rRH2ZNJn1/

ИЗМЕНИТЬ

IMO, непосредственно связывающая обещание с полем, не поддерживается (официально ли это подтверждено?), изменение кода следующим образом будет работать:

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

Здесь плункер: http://run.plnkr.co/plunks/rDo7bFZlBq4rRH2ZNJn1/