Angular 2,使用Angular Cli和Ui Router Ng2,Resolve / Reject

时间:2016-10-20 01:14:04

标签: angular angular-ui-router angular-cli

我有个问题。我使用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示例的内容,因此这些内容都位于与主应用程序模块不同的模块中。

对于整个过程,我仍然非常环保,所以当涉及到控制状态转换的业务逻辑时,我不确定在哪里做准确的工作。

提前致谢!

2 个答案:

答案 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

导入了StateService
import {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

中拿走了

同样,如果有人有更好的解决方案,我就是全力以赴。例如,如何在不强制进行状态更改的情况下实际告知过渡被拒绝。

谢谢!