Có thể chuyển lời hứa đến giao diện người dùng.Xác lý số $state
từ bộ điều khiển bên ngoài (ví dụ: bộ điều khiển kích hoạt trạng thái) không?Vượt qua lời hứa thành bộ điều khiển trạng thái Giao diện người dùng góc-
Tôi biết rằng $state.go()
trả về lời hứa; có thể ghi đè lên số
rằng với lời hứa của riêng bạn
tự giải quyết trực tiếp lời hứa này hoặc giải quyết nó bằng lời hứa mới không?
Ngoài ra, tài liệu cho biết lời hứa trả về $state.go()
có thể bị từ chối với lời hứa khác (được chỉ ra bởi transition superseded
), nhưng tôi không thể tìm thấy bất kỳ nơi nào cho biết điều này có thể được thực hiện từ bên trong chính nhà nước.
Ví dụ: trong mã bên dưới, tôi muốn có thể đợi người dùng nhấp vào nút ($scope.buttonClicked()
) trước khi tiếp tục đến doSomethingElse()
.
Tôi biết rằng tôi có thể phát ra một sự kiện, nhưng vì lời hứa được nướng thành Angular rất sâu, tôi tự hỏi liệu có cách nào để thực hiện điều này thông qua 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)
}]);
Cập nhật Tôi đã chấp nhận câu trả lời @ blint như nó đã khiến tôi gần gũi nhất với những gì tôi muốn. Dưới đây là một số mã xác định ý tưởng của câu trả lời này thêm một chút nữa. Tôi không nghĩ rằng cách tôi đã viết này là một giải pháp rất thanh lịch và tôi hạnh phúc nếu ai đó có thể đề xuất một cách tốt hơn để giải quyết lời hứa từ một trạng thái kích hoạt.
Giải pháp mà tôi đã chọn là kết chuỗi các lời hứa như bình thường trong bộ điều khiển của bạn, nhưng để lại phương thức $scope.next()
(hoặc thứ gì đó tương tự) gắn với phạm vi đó giải quyết/từ chối lời hứa. Kể từ khi nhà nước có thể kế thừa phạm vi của bộ điều khiển cuộc gọi, nó sẽ có thể gọi phương thức đó trực tiếp và do đó giải quyết/từ chối lời hứa. Dưới đây là làm thế nào nó có thể làm việc:
Thứ nhất, thiết lập trạng thái của bạn với các nút/bộ điều khiển mà gọi một phương thức $scope.next()
:
.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>'
});
})
Tiếp theo, bạn thiết lập điều khiển của bạn. Trong trường hợp này, tôi đang sử dụng một phương pháp dịch vụ địa phương, user.loadFromLocalStorage()
để có được bóng lăn (nó trả về một lời hứa), nhưng bất kỳ lời hứa sẽ làm. Trong quy trình làm việc này, nếu $scope.user
thiếu bất kỳ thứ gì, nó sẽ dần dần được điền bằng các trạng thái. Nếu nó được điền đầy đủ, nó sẽ bỏ qua ngay menu chính. Nếu các phần tử bị để trống hoặc đang ở trạng thái không hợp lệ, bạn sẽ được đưa đến chế độ xem lỗi.
.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);
});
});
Điều này là khá dài và chưa đủ, nhưng nó thể hiện ý định chung của điều khiển luồng không đồng bộ bằng lời hứa.
Bạn có ý gì khi 'có thể ghi đè điều đó bằng lời hứa của riêng bạn? '? – blint
Xin lỗi. Tôi đoán cách tốt hơn để nói đó là, bạn có thể giải quyết một lời hứa '$ state' với lời hứa của riêng bạn. – Andrew