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?
(Чтобы уточнить, проблема заключается в различии в поведении между массивом и объектом, возвращенным обещанием. Прямое связывание просто существует как элемент управления)
Ответы
Ответ 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/