dsuryd / dotNetify

Simple, lightweight, yet powerful way to build real-time web apps.
https://dotnetify.net
Other
1.17k stars 164 forks source link

Problem calling two instances #141

Closed ghost closed 5 years ago

ghost commented 5 years ago

Hi dsuryd, I am trying to create a demo using dotnetify and i am having the following issue.

I have created a React component named Demographics. This component connects to CustPosDemographicsDataViewModel via dotnetify.

If i call two instances of the Demographics component like the code below, then i am receiving an error with the following message.

Component is attempting to connect to an already active 'CustPosDemographicsDataViewModel'.
If it's from a dismounted component, you must add vm.$destroy to componentWillUnmount().

` export default class HomePage extends React.Component {

render() {
    return (
        <header className="Home-background">
            <Demographics/>
            <Demographics customerRowId = {7354909}/>
            <SegmentInfo customerId="00000001" customerRowId={7354909}/>
            <br/>
        </header>
    )
}

} `

This means that i can't use the same component twice? I suppose that the each component will create a new instance of viewModel in the back-end.

Here is the code from the Demograpics component:

` export default class Demographics extends Component {

constructor(props) {
    super(props);
    let access_token = window.sessionStorage.getItem('access_token');

    if (access_token) {
        let initialState = {CustomerRowId: this.props.customerRowId};
        this.vm = Dotnetify.react.connect('CustPosDemographicsDataViewModel', this, {
            vmArg: initialState,
            headers: {Authorization: 'Bearer ' + access_token},
            exceptionHandler: ex => this.onException(ex)
        });

    } else {
        // throw exception
    }

    this.state = {
        IsBusy: true,
        CustomerRowId: null,
        DemographicsData: {},
        key: 'general',
    };

    this.dispatchState = state => this.vm.$dispatch(state);
}

componentWillUnmount() {
    this.vm && this.vm.$destroy();
}

render() { ...}

} `

dsuryd commented 5 years ago

The library doesn't support using the same view model instance for multiple components, but there are several workarounds to choose from:

1) Create unique view model class types for each component (sharing code through inheritance). 2) Create a parent container component to connect to the view model, then pass the data as props to the child components. 3) Use the Master-Details pattern (see Doc): create a Master view model and override GetSubVM to return a new instance of the type given the string specified in the client's connect.

ghost commented 5 years ago

That is awesome. Thanks for the solution dsuryd. We are converting a big application from silverlight to React. The viewmodels are transfered easily to dotnet.core and the xaml pages are converted to react components with easy. Instead of rewrite everything from the beginning with dotnetify we can transform the silverlight application into React, very fast.