我有个问题。我使用Angular 2,使用Angular-CLI设置,使用UiRouter(ui-router-ng2)。所有这些都很棒,我正在取得进展。但是,我遇到了一个问题,我确信它很容易解决,我只是不知道该怎么做。
所以我有一个"菜单服务"它从我设置的模拟数据库中获取类别。该服务运行良好,我能够列出类别,并使用这些类别来获取子类别和项目。我正在使用无URL的参数,即我将它们声明为对象,并使用[UiParams]传递它们。所有这一切都运作良好,我甚至可以使用后退按钮' uiSref =" ^"'到达父州。太棒了。但!出于测试目的,我正在使用ui-router-visualizer,我已经遇到了仍然可以转换到状态的问题,即使对象是空的。从我的理解中看,该对象已被解析,并返回为空。这当然可以防止错误,但是如果用户神奇地以子状态结束,则放入一个空对象,然后什么都不显示。这会导致错误本身,因为视图没有内插任何内容。这也导致后退按钮发生故障,因为ui-params不可用。
现在,所有这些都说,如果菜单服务中的返回对象为空,我如何拒绝状态转换?
代码对于州。我正在使用Ng2StateDeclaration。
{
name:'category',
parent:'main.categories',
params:{
categoryid:{}
},
views:{
'$default@main': { component: SubcategoryComponent },
receipt: { component: ReceiptComponent }
},
resolve:[
{
token:'category',
deps: [Transition, MenuService],
resolveFn: (trans, menuSvc) => {
menuSvc.getCategory(trans.params().categoryid)
}
}
]
}`
以下是菜单服务的完整代码。这非常简单。
import { Injectable, Inject } from '@angular/core';
import { Headers, Http, Response} from '@angular/http';
import 'rxjs/add/operator/toPromise';
@Injectable()
export class MenuService {
constructor(@Inject(Http) public http:Http) { }
getCategories() {
return this.http.get('api/menu')
.map(this.extractData)
.toPromise();
}
private extractData(res: Response) {
let body = res.json();
return body.data || { };
}
getCategory(id){
console.log(id);
return this.getCategories()
.then(cats => cats.find(cat => cat.id == id));
}
}
还有组件,也非常基础。我正在使用他们的quickstart-app作为我的主要学习工具。
import { Component, Input, Inject } from '@angular/core';
@Component({
templateUrl: './subcategory.component.html',
styleUrls: ['./subcategory.component.css'],
inputs: ["category"],
})
export class SubcategoryComponent {
category;
}
如果有人能指出我回答这个问题的某个地方,或者告诉我在哪里以及如何输入一个返回对象或拒绝状态转换的If / Else语句,那就太棒了。我也在构建类似quickstart示例的内容,因此这些内容都位于与主应用程序模块不同的模块中。
对于整个过程,我仍然非常环保,所以当涉及到控制状态转换的业务逻辑时,我不确定在哪里做准确的工作。
提前致谢!
答案 0 :(得分:2)
现在,所有这些都说,如果菜单服务中的返回对象为空,我如何拒绝状态转换?
如果resolve函数返回被拒绝的promise,则转换将错误且不会运行。由于你的getCategory函数返回并且没有找到空对象(而不是被拒绝的promise),你将不得不在服务中或在解析中拒绝它。
无论哪种方式,你都可以写一个这样的帮手:
const rejectWhenEmpty = (val) =>
val ? val : Promise.reject('value is empty)
然后在没有加载值时使用它来拒绝解析
resolveFn: (trans, menuSvc) =>
menuSvc.getCategory(trans.params().categoryid).then(rejectWhenEmpty)
或在服务中:
getCategory(id){
return this.getCategories()
.then(cats => cats.find(cat => cat.id == id))
.then(rejectWhenEmpty);
}
答案 1 :(得分:1)
所以我已经解决了我自己的问题。这可能不是最好的方式,所以我总是愿意接受更好的解决方案。但是现在它对我有用。
我从ui-router-ng2
导入了StateServiceimport {Ng2StateDeclaration,Transition, StateService} from 'ui-router-ng2';
然后我获取返回的项目,状态服务和trans.from()参数,并通过.then
将其传递给第二个函数。deps: [Transition, MenuService, StateService],
resolveFn: (trans, itemSvc, $state) => {
return itemSvc.getItems(trans.params().groupid).then(items =>{
return stateContinue(items, $state, trans.from());
})
}
状态继续功能
function stateContinue(thing, $state, from){
if (!isEmpty(thing)){
return thing;
}else {
$state.go(from);
}}
这就是"""不是空的,它将返回"事物"。否则,您将返回给您之前的状态/不会离开当前状态。
isEmpty函数是
function isEmpty(obj) {
if (obj == null) return true;
if (obj.length > 0) return false;
if (obj.length === 0) return true;
if (typeof obj !== "object") return true;
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) return false;
}
return true; }
我毫不掩饰地从这个is-empty-object q/a
中拿走了同样,如果有人有更好的解决方案,我就是全力以赴。例如,如何在不强制进行状态更改的情况下实际告知过渡被拒绝。
谢谢!