2

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

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:这是答案-> ngRepeat 内的 Angular UI Bootstrap 模态

4

4 回答 4

2

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

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

.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在 promise 解决之前将是未定义的,然后它将变为已定义并解析为"text". 因此,您的视图应该在短时间内处理未定义状态 - 通常使用ng-show.

于 2014-08-12T11:20:51.660 回答
1

控制器.js:

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

一些服务.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>
于 2014-08-12T11:02:07.310 回答
0

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

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

更新:

创建一个$scope将值分配给value变量的函数。

控制器

$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>
于 2014-08-12T10:24:19.063 回答
0

为了扩展 Ed Hinchliffe 的回答,如果您想返回一个实际对象,一旦解决了承诺,该对象就会被填充,您可以执行类似的操作。(与他的回答类似,但使用 $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; 
}
于 2014-11-08T05:41:45.577 回答