AngularJS承诺返回空对象

时间:2014-08-12 10:20:47

标签: angularjs q angular-promise

基本上我想要做的是从函数调用中分配一些解决promise的模型值。像这样

value = someFun()

这是我称之为此功能的服务

app.factory('SomeService', function($q) {
    return {
        someFun: function() {
            var d = $q.defer();
            try {
                d.resolve("hi");
            } catch (e) {
                d.reject(e);
            }
            return d.promise.then(function(text){
                return text;
            });
        }
    };
});

这是HTML代码

<div ng-init="value = 'yes'">
    <pre>{{value |json}}</pre>
</div>
<button type="button" ng-click="value = someFun()">click me</button>

这是在控制器中

$scope.someFun = SomeService.someFun;

这是plnkr

http://plnkr.co/edit/qO5ofBXZDsi3cS3bBnT8

现在它返回一个空对象。有什么问题?

编辑:正如下面已经回答的那样,是的,这是一种方式,但是我想说我想在ngRepeat中调用SomeService.someFun?

EDIT2:这是答案 - &gt; Angular UI Bootstrap modal inside ngRepeat

4 个答案:

答案 0 :(得分:2)

通常,如果你想使用异步更新的东西出现在视图中而不必编写控制器代码(在你的问题就是这种情况,因为你想在ng-view中调用函数),那么您需要返回一个空白占位符对象,并将promise的结果合并到其中,或者更新您可以在视图中引用的该对象的属性。

你的问题太抽象了,无法知道解决这个问题的确切方法对你的应用程序有意义,但这里是一般的(和抽象的)想法plunker here

.factory('promiseService', function($q){
  return {
    someDeferredThing: function(){
      var placeholder = {};
      var d = $q.defer();
      d.promise.then(function(text){
        placeholder.text = text;
      });
      d.resolve("hi");
      return placeholder;
    }
  }
)

服务返回一个由promise更新的对象,一个promise本身。如果您返回承诺,则必须处理.then()等以获取价值。

.controller('appCtrl', function($scope, promiseService){
  $scope.deferredResult = promiseService.someDeferredThing();
});

这是将值分配给范围的方法。

在承诺结算之前,

$scope.deferredResult.text将被定义,然后它将被定义并解析为"text"。因此,您的视图应该在短时间内处理未定义的状态 - 通常使用ng-show非常简单。

答案 1 :(得分:1)

Controller.js:

  $scope.someFun = function () {
        return someservice.someFun().then(function (data) {
            $scope.value = data;
        });
    }

someservice.js:

    function someFun() {
        var d = $q.defer();
        try {
            d.resolve("hi");
        } catch (e) {
            d.reject(e);
        }
        return d.promise;
    }

HTML:

 <div ng-init="value = 'yes'">
                <pre>{{value |json}}</pre>
            </div>
            <button type="button" ng-click="someFun()">click me</button>

答案 2 :(得分:0)

promise.then()会返回 AngularJS Documentation 中所述的承诺。如果你想获得价值,你应该这样做:

SomeService.someFun.then(function(text) {
  $scope.someFun = text;
});

更新

创建一个$scope函数,该函数将为value变量赋值。

<强> CONTROLLER

$scope.setValue = function() {
  SomeService.someFun.then(function(text) {
      $scope.value = text;
  });
};

<强> HTML

<div ng-init="value = 'yes'">
    <pre>{{value |json}}</pre>
</div>
<button type="button" ng-click="setValue()">click me</button>

答案 3 :(得分:0)

为了扩展Ed Hinchliffe的答案,如果你想要返回一个实际的对象,一旦一个promise得到解决,它就会被填充,你可以做这样的事情。 (与他的答案类似,但使用$ http作为示例异步操作)然后将结果复制到返回的placeholder引用的硬编码属性中,而不是将从$ http接收的对象的所有属性复制到已返回的placeholder的现有引用。当然,这是假设您想要返回一个对象。我假设这与$ resource在返回对象时内部的工作方式类似。

function getObjectToBeFilledByPromise() {
    var placeholder = {};            // Create a reference to return
    var deferred = $q.defer();       // This will handle your promise

    deferred.promise.then(function(data) {  // Once our promise is resolved, populate object

        // Add all properties of data into the existing placeholder reference which was already returned
        for(var attr in data) {
            placeholder[attr] = data[attr];
        }

    });

    // Some Asynchronous Operation...
    $http({
        method: 'GET',
        url: yourUrl
    })
    .success(function(data) {
        deferred.resolve(data); // Resolve promise, which will be handled above
    })

    // Return reference as it exists now.  
    // It will be populated once the promise is resolved
    return placeholder; 
}