AngularJS - binding/watching a function which retu

2019-05-09 06:29发布

问题:

I posted an issue on the AngularJS github but it doesn't seem to be getting a whole lot of attention and I wasn't able to fix it myself since it's a pretty low-level issue, so I think it's time to look for a workaround.

Angular allows you to put a promise (or anything with a .then(...) function) into your scope, and once it is resolved, all $watches and anything bound to that promise will use the resolved value. The issue arises when you use a function to return a promise, as the same doesn't apply - it's handled like a plain object.

For example:

var helloDef = $.Deferred();
$scope.hello = helloDef.promise();

$scope.getHello = function() {
    return $scope.hello;
};

$timeout(function() {
    helloDef.resolve('Hello!');
}, 1000);

Fiddle

Here using ng-bind="hello" works fine and outputs Hello!, but ng-bind="getHello()" outputs [object Object] as the internal $watch returns the promise object. Works the same way with $q instead of $.Deferred.

In my actual code I'm creating the promise the first time the function is called, so I can't just pre-make the promise and refer to that in scope.

I also need it for more than just ng-bind, so making my own binding directive which handles this case properly isn't viable.

Anyone have any ideas? I'm currently returning the promise if the data hasn't resolved and the actual result if it has, but that's a pain to work with. Anything bound to the data briefly causes weird side effects as the data is being loaded, like ngRepeat using the promise object instead of the resolved value to create elements.

Thanks.

UPDATE: Pull request: https://github.com/angular/angular.js/pull/3605

UPDATE 2: For future reference, automatic promise unwrapping has been deprecated in the 1.2 brach.

回答1:

For some things, I use $resource. If I need to wait for it, $then works well:

var r = $resource...get...
var p = r.$then...

Otherwise, I build my own resource-like object that is not a promise, but has a promise that I can wait for.



回答2:

Pull request merged, it should be fixed in 1.2.0 so I'll mark this as the answer.