gpt4 book ai didi

javascript - 将 promise 传递给 Angular-UI 状态 Controller

转载 作者:搜寻专家 更新时间:2023-11-01 04:17:05 25 4
gpt4 key购买 nike

是否可以从外部 Controller (例如触发状态的 Controller )向 UI.Router $state 传递 promise ?

我知道 $state.go() 返回一个 promise ;是否可以 用你自己的 promise 覆盖它 自己直接解决这个 promise 或使用新的 promise 解决它?

另外,文档说 $state.go() 返回的 promise 可以被另一个 promise 拒绝(由 transition superseded 表示),但我不能找到表明如何从国家内部完成此操作的任何地方。

例如,在下面的代码中,我希望能够等待用户点击按钮 ($scope.buttonClicked()),然后再继续 doSomethingElse ()

我知道我可以发出一个事件,但由于 promises 在 Angular 中的根基如此之深,我想知道是否有办法通过 promise.resolve/promise.reject 来做到这一点

angular.module('APP', ['ui.router'])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('myState', {
template: '<p>myState</p>',
controller: ['$state', '$scope', '$q', function ($state, $scope, $q) {
var deferred = $q.defer();

$scope.buttonClicked = function () {
deferred.resolve();
}
}]
});
}])
.controller('mainCtrl', ['$state', function ($state) {
$state.go('myState')
.then(doSomethingElse)
}]);

更新我接受了@blint 的回答,因为它让我最接近我想要的。下面是一些代码,可以进一步充实这个答案的想法。我不认为我写这篇文章的方式是一个非常优雅的解决方案,如果有人可以提出更好的方法来解决触发状态的 promise ,我很高兴。

我选择的解决方案是像往常一样在 Controller 中链接您的 promise ,但将 $scope.next() 方法(或类似的方法)附加到解析的范围/拒绝 promise 。由于状态可以继承调用 Controller 的作用域,它将能够直接调用该方法,从而解决/拒绝 promise 。以下是它的工作原理:

首先,使用调用 $scope.next() 方法的按钮/ Controller 设置状态:

.config(function ($stateProvider) {
$stateProvider
.state('selectLanguage', {
template: '<p>Select language for app: \
<select ng-model="user.language" ng-options="language.label for language in languages">\
<option value="">Please select</option>\
</select>\
<button ng-click="next()">Next</button>\
</p>',
controller: function ($scope) {
$scope.languages = [
{label: 'Deutch', value: 'de'},
{label: 'English', value: 'en'},
{label: 'Français', value: 'fr'},
{label: 'Error', value: null}
];
}
})
.state('getUserInfo', {
template: '<p>Name: <input ng-model="user.name" /><br />\
Email: <input ng-model="user.email" /><br />\
<button ng-click="next()">Next</button>\
</p>'
})
.state('mainMenu', {
template: '<p>The main menu for {{user.name}} is in {{user.language.label}}</p>'
})
.state('error', {
template: '<p>There was an error</p>'
});
})

接下来,您将设置您的 Controller 。在这种情况下,我使用本地服务方法 user.loadFromLocalStorage() 来启动(它返回一个 promise ),但任何 promise 都可以。在此工作流程中,如果 $scope.user 缺少任何内容,它将逐渐使用状态填充。如果它已完全填充,它会直接跳到主菜单。如果元素留空或处于无效状态,您将进入错误 View 。

.controller('mainCtrl', function ($scope, $state, $q, User) {
$scope.user = new User();

$scope.user.loadFromLocalStorage()
.then(function () {
var deferred;

if ($scope.user.language === null) {
deferred = $q.defer();

$state.go('selectLanguage');

$scope.next = function () {
$scope.next = undefined;

if ($scope.user.language === null) {
return deferred.reject('Language not selected somehow');
}

deferred.resolve();
};

return deferred.promise;
}
})
.then(function () {
var deferred;

if ($scope.user.name === null || $scope.user.email === null) {
deferred = $q.defer();

$state.go('getUserInfo');
$scope.next = function () {
$scope.next = undefined;

if ($scope.user.name === null || $scope.user.email === null) {
return deferred.reject('Could not get user name or email');
}

deferred.resolve();
};

return deferred.promise;
}


})
.then(function () {
$state.go('mainMenu');
})
.catch(function (err) {
$state.go('error', err);
});

});

这很冗长,还不是很干,但它显示了使用 promises 进行异步流控制的总体意图。

最佳答案

目的promises是保证结果...或处理失败。 Promise 可以链接起来,在函数中返回,从而进行扩展。

您不会对“覆盖” promise 感兴趣。但是,您可以做什么:

  • 处理失败案例。这是文档中的示例:
promiseB = promiseA.then(function(result) {
// success: do something and resolve promiseB
// with the old or a new result
return result;
}, function(reason) {
// error: handle the error if possible and
// resolve promiseB with newPromiseOrValue,
// otherwise forward the rejection to promiseB
if (canHandle(reason)) {
// handle the error and recover
return newPromiseOrValue;
}
return $q.reject(reason);
});
  • 在 promise 链中追加一个新的异步操作。你可以结合 promise 。如果链中调用的方法返回一个 promise ,一旦新 promise 得到解决, promise 的父级将隔离链的其余部分。

这是您可能正在寻找的模式:

angular.module('APP', ['ui.router'])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('myState', {
template: '<p>myState</p>',
controller: 'myCtrl'
});
}])
.controller('myCtrl', ['$scope', '$state', '$q', '$http', 'someAsyncServiceWithCallback',
function ($scope, $state, $q, $http, myService) {
$scope.buttonClicked = function () {
$state.go('myState')
.then(function () {
// You can return a promise...
// From a method that returns a promise
// return $http.get('/myURL');

// Or from an old-school method taking a callback:
var deferred = $q.defer();
myService(function(data) {
deferred.resolve(data);
});

return deferred.promise;
},
function () {
console.log("$state.go() failed :(");
});
};
}]);

关于javascript - 将 promise 传递给 Angular-UI 状态 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23492349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com