将数据传递到Aurelia中尚未加载的视图 [英] Pass data to not-yet-loaded view in Aurelia

查看:65
本文介绍了将数据传递到Aurelia中尚未加载的视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从一个视图(称为bestSellersView)导航到另一个(BookDetailsView)视图.有多个不同的父"视图可以导航到图书详细信息",并且它们都需要将要查看的图书传递到下一个视图.我不想像某些线程所建议的那样将源视图注入到详细信息视图中,因为我的构造函数会随使用该详细信息子视图的每个新视图一起增长.

I am navigating from one view (call it bestSellersView) to another (BookDetailsView). There are multiple different 'parent' views that can navigate to 'Book Details' and they all need to pass the book that is to be viewed to the next view. I don't want to inject the source view to the details view as some threads suggest since my constructor would grow with each new view that uses the details sub-view.

我正在尝试使用事件聚合器,但是由于事情的生命周期,我第一次导航时总是出现空白的详细信息屏幕.当我第一次导航到书籍详细信息"视图时,在发布者(畅销书)发送消息之前,尚未订阅ViewDetailsMessage.由于我将viewmodel设置为singleton,因此随后的点击可以正常工作(因为详细信息视图已经构建并订阅了该事件).

I am trying to use the event aggregator, however due to the life cycle of things I am always getting a blank details screen on the first time I navigate. When I first navigate to the 'book details' view the ViewDetailsMessage has not yet been subscribed to before the publisher (best sellers) sends the message. Since I have my viewmodel set to singleton, the subsequent clicks work fine (since the details view is already constructed and subscribed to the event).

在Aurelia,如何解决这个鸡蛋问题?

How can I get around this chicken-egg problem in Aurelia?

编辑01

这是我遇到问题时正在做的事情:

Here is what I was doing when I was having a problem:

Master.ts:

Master.ts:

import { JsonServiceClient } from "servicestack-client";
import {
    ListPendingHoldingsFiles,
    ListPendingHoldingsFilesResponse,
    SendHoldings,
    PositionFileInfo
} from "../holdingsManager.dtos";
import { inject, singleton } from "aurelia-framework";
import { Router } from "aurelia-router";
import { EventAggregator } from "aurelia-event-aggregator";
import { GetPendingPositionMessage } from "../common/GetPendingPositionMessage";

@singleton()
@inject(Router, EventAggregator)
export class Pending {
    router: Router;
    positions: PositionFileInfo[];
    client: JsonServiceClient;
    eventAgg: EventAggregator;

    constructor(router, eventAggregator) {
        this.router = router;
        this.eventAgg = eventAggregator;
        this.client = new JsonServiceClient('/');
        var req = new ListPendingHoldingsFiles();
        this.client.get(req).then((getHoldingsResponse) => {
            this.positions = getHoldingsResponse.PositionFiles;
        }).catch(e => {
            console.log(e); // "oh, no!"
        });
    }

    openHoldings(positionInfo) {
        this.eventAgg.publish(new GetPendingPositionMessage(positionInfo));
        this.router.navigate('#/holdings');
    }
}

Child.ts:

import { JsonServiceClient } from "servicestack-client";
import { inject, singleton } from "aurelia-framework";
import { Router } from 'aurelia-router';
import { EventAggregator } from "aurelia-event-aggregator";
import { GetPendingPositionMessage } from "../common/GetPendingPositionMessage";
import {
    GetPendingHoldingsFile,
    GetPendingHoldingsFileResponse,
    Position,
    PositionFileInfo
} from "../holdingsManager.dtos";

@singleton()
@inject(Router, EventAggregator)
export class Holdings {
    router: Router;
    pendingPositionFileInfo: PositionFileInfo;
    position: Position;
    client: JsonServiceClient;
    eventAgg: EventAggregator;

    constructor(router, eventAggregator) {
        this.router = router;
        this.eventAgg = eventAggregator;
        this.eventAgg.subscribe(GetPendingPositionMessage,
            message => {
                this.pendingPositionFileInfo = message.fileInfo;
            });
    }

    activate(params, routeData) {
        this.client = new JsonServiceClient('/');
        var req = new GetPendingHoldingsFile();
        req.PositionToRetrieve = this.pendingPositionFileInfo;
        this.client.get(req).then((getHoldingsResponse) => {
            this.position = getHoldingsResponse.PendingPosition;
        }).catch(e => {
            console.log(e); // "oh, no!"
        });
    }
}

这是我现在正在做的事情:

Here is what I am doing now:

master.ts

master.ts

import { JsonServiceClient } from "servicestack-client";
import {
    ListPendingHoldingsFiles,
    ListPendingHoldingsFilesResponse,
    PositionFileInfo
} from "../holdingsManager.dtos";
import { inject, singleton } from "aurelia-framework";
import { Router } from "aurelia-router";
import { EventAggregator } from "aurelia-event-aggregator";
import { GetPendingPositionMessage } from "../common/GetPendingPositionMessage";
import { SetPendingPositionMessage } from "../common/SetPendingPositionMessage";

@singleton()
@inject(Router, EventAggregator)
export class Pending {
    router: Router;
    eventAgg: EventAggregator;
    positions: PositionFileInfo[];
    client: JsonServiceClient;
    fileInfo: PositionFileInfo;

    constructor(router, eventAggregator) {
        this.router = router;
        this.eventAgg = eventAggregator;
        this.eventAgg.subscribe(GetPendingPositionMessage, () => {
            this.eventAgg.publish(new SetPendingPositionMessage(this.fileInfo));
        });
    }

    activate(params, routeData) {
        this.client = new JsonServiceClient('/');
        var req = new ListPendingHoldingsFiles();
        this.client.post(req).then((getHoldingsResponse) => {
            this.positions = getHoldingsResponse.PositionFiles;
        }).catch(e => {
            console.log(e); // "oh, no!"
        });
    }

    openHoldings(positionInfo) {
        this.fileInfo = positionInfo;
        this.router.navigate('#/holdings');
    }
}

child.ts

import { JsonServiceClient } from "servicestack-client";
import { inject, singleton } from "aurelia-framework";
import { Router } from 'aurelia-router';
import {
    GetPendingHoldingsFile,
    GetPendingHoldingsFileResponse,
    Position,
    SendHoldings,
    PositionFileInfo
} from "../holdingsManager.dtos";
import { EventAggregator } from "aurelia-event-aggregator";
import { GetPendingPositionMessage } from "../common/GetPendingPositionMessage";
import { SetPendingPositionMessage } from "../common/SetPendingPositionMessage";
import { GetDeliveredPositionMessage } from "../common/GetDeliveredPositionMessage";
import { SetDeliveredPositionMessage } from "../common/SetDeliveredPositionMessage";

@singleton()
@inject(Router, EventAggregator)
export class Holdings {
    router: Router;
    pendingPositionFileInfo: PositionFileInfo;
    position: Position;
    client: JsonServiceClient;
    eventAgg: EventAggregator;

    constructor(router, eventAggregator) {
        this.router = router;
        this.eventAgg = eventAggregator;
        this.eventAgg.subscribe(SetPendingPositionMessage, message => this.getPositionData(message.fileInfo));
        this.eventAgg.subscribe(SetDeliveredPositionMessage, message => this.getPositionData(message.fileInfo));
    }

    getPositionData(fileInfo) {
        this.position = null;
        this.client = new JsonServiceClient('/');
        var req = new GetPendingHoldingsFile();
        req.PositionToRetrieve = fileInfo;
        this.client.post(req).then((getHoldingsResponse) => {
            this.position = getHoldingsResponse.PendingPosition;
        }).catch(e => {
            console.log(e); // "oh, no!"
        });
    }

    activate(params) {
        this.eventAgg.publish(new GetPendingPositionMessage());
        this.eventAgg.publish(new GetDeliveredPositionMessage());
    }

    sendHoldings() {
        var req = new SendHoldings();
        this.client.get(req).then((sendHoldingsRepsonse) => {
            console.log("SUCCESS!"); // "oh, no!"
        }).catch(e => {
            console.log(e); // "oh, no!"
        });
    }
}

我需要在孩子的激活方法上添加一些逻辑,以确保我要求正确的父母持股文件.

I need to add a bit of logic to the activate method of the child to ensure I ask for the right parents holdings file.

推荐答案

听起来像您需要在视图之间共享状态.我使用一个StateStore类,该类被注入希望共享状态的任何视图中.默认情况下,所有注入的对象都是 Singletons ,从而易于共享状态.一个非常简单的示例可能是(在TypeScript中):

Sounds like you need to share state between views. I use a StateStore class that is injected into any views that wish to share state. By default all objects injected are Singletons making it easy to share state. A very simple example could be (in TypeScript):

statestore.ts

statestore.ts

export class StateStore {
    state: any;
}

masterview.ts

masterview.ts

autoinject()
export class MasterView {
    constructor(private store: StateStore){
    }

    doSomething(): void {
        this.store.state = "some value";
        // navigate to detail view
    }
}

detailview.ts

detailview.ts

autoinject()
export class DetailView {
    sharedValue: any;

    constructor(store: StateStore) {
        this.sharedValue = store.state;
    }
}

这将在视图之间共享StateStore的单个实例,从而易于共享状态.

This will share a single instance of StateStore between views allowing state to easily be shared.

这篇关于将数据传递到Aurelia中尚未加载的视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆