dsuryd / dotNetify

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

Calling event at page load #178

Closed Simcon closed 5 years ago

Simcon commented 5 years ago

Hi, this goes back to my earlier post #171 where I'm still trying to get something to happen immediately on page load (eg. post back a querystring value).

I've gone back to your startup example and am trying to call serverside code immediately after page load.

In the following code what should happen is the mounted function calls onstartup which calls the dispatch. mounted definitely gets called as the console log event 'onstartup' shows but the dispatch never happens.

If I press the button, which calls startup, everything works fine.

I think this is because the connection isn't ready since the "WebSocket connected to ws://localhost..." comes after the 'onstartup' log event. If this is the case how can I invoke immediately after websocket connect (without timer!).

<div id="App">
    <div>
        <p>{{Greetings}}</p>
        <p>Server time is: {{ServerTime}}</p>
        <p>Disney: {{Mickey}}</p>
        <button onclick="vue.onstartup();">this works</button>
    </div>
</div>

<script>
    var vue = new Vue({
        el: '#App',
        created: function() { this.vm = dotnetify.vue.connect("HelloWorld", this) },
        mounted: function () {
            this.onstartup();
        },
        data: { Greetings: '', ServerTime: '', Mickey: 'this gets overwritten' },
        methods: {
            onstartup: function () {
                console.log('onstartup');
                this.vm.$dispatch({ DoIt: { } });
            }
        }
    });

Thanks, Paul

https://github.com/Simcon/DotnetifyStart

Simcon commented 5 years ago

So it looks like I can hook into another event, eg:

v-vm-on="{ Greetings: onstartup }

but it's a bit of a fudge relying on another value. Is there a better way?

dsuryd commented 5 years ago

In that other issue I proposed using beforeUpdate to intercept receiving initial state which is a sure indication that the connection is ready. Did that not work out? Also, why a dispatch right after mount? If it's for initialization of the view model, you could include the state in the connect.

Simcon commented 5 years ago

I tried on beforeUpdate and that didn't work. Let me go around again and try connect. Thanks!

Simcon commented 5 years ago

Hi Dicky, thanks for the pointers. I managed to get it working on connect as you suggested.

For reference for others:

On the client:

        var vue = new Vue({
            el: '#App',
            data: {
                Id: '',
                Graph: ''
            },
            created: function() {
                var id = '@ViewData["Id"]';
                this.vm = dotnetify.vue.connect("GraphVm", this, { vmArg: { Id: id } });
            }
        });

On the server:

        private string _id;
        public string Id
        {
            get { return _id; }
            set
            {
                if (_id != value)
                {
                    _id = value;
                    InitialiseGraph();
                }
            }
        }

        private void InitialiseGraph()
        {
            Graph = getTheData);
        }

        public string Graph
        {
            get => Get<string>();
            set => Set(value);
        }