Angular 2,使用 Angular Cli,和 Ui 路由器 Ng2,Resolve/Reject

Angular 2, using Angular Cli, and Ui Router Ng2, Resolve/Reject

我有一个问题要问你们。我正在使用 Angular 2,通过 Angular-CLI 和 UiRouter (ui-router-ng2) 进行设置。所有这些都很棒,我正在取得进步。但是,我 运行 遇到了一个问题,我确信这个问题很容易解决,只是不知道该怎么做。

所以我有一个 "menu service",它从我设置的模拟数据库中获取类别。该服务运行良好,我能够列出类别,并使用这些类别获取子类别和项目。我正在使用 URL-less 参数,即我将它们声明为对象,并使用 [UiParams] 传递它们。所有这些都运行良好,我什至可以使用后退按钮 'uiSref="^"' 进入父状态。都很棒。但!出于测试目的,我正在使用 ui-router-visualizer,我遇到了一个问题,即使对象是空的,我仍然可以转换到一个状态。看,根据我的理解,对象已解析,并且 return 为空。这当然可以防止错误,但是如果用户神奇地进入子状态,则放置一个空对象,然后什么也不会显示。这本身会导致错误,因为视图没有任何可插入的内容。这也会导致后退按钮出现故障,因为 ui-params 不可用。

现在,综上所述,如果我的菜单服务中的 return 对象为空,我该如何拒绝状态转换?

州代码。为此,我正在使用 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 声明 return 是对象或拒绝状态转换,那太棒了。我也在构建 quickstart 示例之类的东西,所以这一切都位于与主应用程序模块不同的模块中。

我对整个过程还是很陌生,所以当涉及到业务逻辑控制状态转换时,我不太确定具体在哪里工作。

提前致谢!

所以我已经解决了我自己的问题。这可能不是最好的方法,所以我总是愿意接受更好的解决方案。但目前对我有用。

我从 ui-router-ng2

导入了 StateService
import {Ng2StateDeclaration,Transition, StateService} from 'ui-router-ng2';

然后我获取 returned 项、状态服务和 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);
}}

如果 "thing" 不为空,它将 return "thing"。否则你将 return 告诉你以前 state/won 不会离开当前状态。

而 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

同样,如果有人有更好的解决方案,我完全赞成。例如,如何在不强制状态更改的情况下实际告诉转换被拒绝。

谢谢!

Now, all of that being said, how do I reject the state transition if the return object from my menu service is empty?

如果 resolve 函数 returns 一个被拒绝的承诺,转换将出错而不是 运行。由于您的 getCategory 函数 returns 和空对象(如果未找到)(而不是被拒绝的承诺),您将不得不在服务或解析中拒绝它。

无论哪种方式,您都可以像这样编写一个助手:

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);
}