AngularJS承诺

10

AngularJS文档说:

$q promises在angular的模板引擎中得到了认可,这意味着在模板中,您可以将附加到作用域的promises视为结果值。

那么,有人可以解释一下为什么这个演示无法工作吗?它不能更改文本字段的值。但是将$http服务返回的promises分配给作用域字段就像魔法一样起作用。

控制器:

function MyController($scope, $q, $timeout) {
    this.getItem = function () {
        var deferred = $q.defer();
        deferred.resolve({
            title: 'Some title'
        });
        return deferred.promise;
    };

    $scope.item = this.getItem();
}

Html:

<input type="text" ng-model="item.title">

你能展示一下你如何分配一个由 $http 返回的 Promise,以便它按照你想要的方式工作吗? - Dogbert
@DogbertпјҢиҝҷжҳҜдјӘд»Јз ҒпјҢз”ЁдәҺиҜҙжҳҺжҲ‘жүҖиҜҙзҡ„пјҡ$scope.item = $http({method: 'post', url: '/find/my/item/'}) .then(function (response) { return response.item; });еҸҰдёҖдёӘдҪҝз”Ё$resourceж–№жі•зҡ„дҫӢеӯҗеҸҜд»ҘеңЁиҝҷдёӘж•ҷзЁӢдёӯжүҫеҲ°гҖӮд»ҺиҝҷдёҖиЎҢејҖе§ӢпјҡжіЁж„ҸпјҢеңЁPhoneListCtrlдёӯжҲ‘们用$ scope.phones = Phone.query()жӣҝжҚўдәҶ... - Raman Chodźka
糟糕,刚刚创建了一个测试示例(http://plnkr.co/edit/VP1Td3WtdM0E7n5HJH3W?p=preview),但似乎无法与任何承诺一起使用。 - Raman Chodźka
嘿,大家好,为了让它正常工作,我不得不使用.success(function(){}).then(function(r){if (r.data["my-result"])return r.data["my-result"];}); - Joel
3个回答

14

您需要在 Promise 对象上使用 then() 函数:

this.getItem().then(function(result) {
   $scope.item = result;
});

在你的情况下,我认为你不需要一个Promise。Angular的$watch系统会照顾好一切。只需在函数中返回一个对象,而不是一个基本类型:

this.getItem = function () {
    var item = {};

    // do some async stuff
    $http.get(...).success(function(result) {
       item.title = result;
    });
    return item;
};

$scope.item = this.getItem();

我知道你的意思。我已经更新了我的答案。你必须让Angular来处理它(它会通过其$watch系统自动完成)。 - asgoth
你给出的第二个例子看起来并不比第一个简单 ;) 此外,它不会按预期工作,因为$http.get()将被解析为代表_item_的json,而不仅仅是_title_ 所以 this.getItem().then(function(result) { $scope.item = result; }); 看起来相当可接受(我只是将this.item = result更改为$scope.item = result) - Raman Chodźka
啊,确实这应该是作用域的问题。我会更改它,以便您可以接受它。 - asgoth
我不确定这是否解决了AngularJS声称承诺可以在绑定期间像结果一样使用的事实...文档仍然这样说,我想知道为什么他的代码不起作用。也许只有在模板完成消化后延迟解决时才有效?在返回承诺之前同步解决不是典型的做法。 - TheXenocide

1

我认为你的第一个小提琴不起作用的原因是因为你实际上将作用域属性item绑定到了一个Promise。当你尝试通过输入文本框来改变值时,Angular会注意到这个活动,然后重新分配/重置item的值为Promise的结果(这没有改变)。

@asgoth提供的解决方案在Promise解决时一次性设置/分配item的值。这里没有绑定(即item未绑定到Promise),因此通过文本框更改值确实会更改值。


-1

就像@Mark所说的那样,在这里你可以找到你代码片段的工作示例

基本上,你返回的是一个对象而不是绑定模型本身。

$timeout(function(){
   $scope.item = {
      title: 'Some title'
   }; // Apply the binding
   deferred.resolve(); // Resolve promise
},2000); // wait 2 secs           

你的 JavaScript 最后一行应该只是 this.getItem(); - Mark Rajcok

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接