10

我正在尝试从 AngularJs (1.0.7) 中的承诺中返回一条记录,并将结果绑定到表单。表单绑定正确,但输入字段是只读的 - 我无法编辑值。

相反,如果我将记录包装在一个数组中并使用 ng:repeat 进行迭代,则表单将正确绑定并且我可以编辑值。

我创建了一个 plnkr 来清楚地展示这个问题:

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

您可以编辑直接绑定和列表绑定的输入字段,但无法编辑绑定到单个 Promise 的字段。

是否可以将 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') 组件,但直接写入承诺对象本身。

尝试编辑 promise 时,ViewModel 会不断恢复为原始值,同时将字符存储在 promise 本身上。因此,如果用户在输入字段中键入“asdf”,结果将如下所示。

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

而我们应该期待

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

我做错了什么,或者这可能是AngularJS中的一个错误?

(为了进一步澄清,问题在于 Array 和由 promise 返回的 Object 之间的行为差​​异。直接绑定只是作为控件存在)

4

1 回答 1

8

更新

似乎AngularJS 1.0.3已经引入了这个问题:http: //jsfiddle.net/sonicsage/k8W4Y/6/

如果你切换到 AngularJS 1.0.2,它会工作。

GitHub 上有一个未解决的问题:https ://github.com/angular/angular.js/issues/1827

Google Groups上的原始线程。

这里还有一个关于自动展开的有趣线程: https ://github.com/angular/angular.js/pull/1676


通过在 Chrome 控制台中调试应用程序,您可以看到它single是一个函数(promise):

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

Whiledirect是一个对象:

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

但是,在只读输入上按下键对 有影响promise,例如,选择所有文本并擦除它,虽然对 UI 没有影响,但对属性有影响:

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

您可以在此处进一步调试应用程序:http ://run.plnkr.co/plunks/rDo7bFZlBq4rRH2ZNJn1/

编辑

不支持 IMO 直接将 promise 绑定到字段(这是官方记录的吗?),如下更改代码将起作用:

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

这是 plunker:http: //run.plnkr.co/plunks/rDo7bFZlBq4rRH2ZNJn1/

于 2013-06-02T13:52:15.200 回答