Comments (19)
Just did a quick glance, may or may not be related to the main issue, but it's something to fix:
should be:
this.vm = dotnetify.react.connect("RunChart", this);
from dotnetify.
You're a life saver! So it was just simple as me forgetting to revert back to using props instead of state when I made the component "display only"?
from dotnetify.
Calling the $dispatch right after connect won't work because connect is async. Use this instead:
this.vm = dotnetify.react.connect("RunFeedRow", this, {vmArg: {Run: this.props.Run} });
The vmArg allows you to initialize one or more properties of the view model.
Make sure you are using npm dotnetify v2.0.5-beta.
from dotnetify.
Thanks for the quick response! I think this may be a design issue on my part as I'm using Mediatr and trying to get an event up to the view model. I think Mediatr may be sending the event to its own instance of the view model. I will keep you posted.
from dotnetify.
OK. But in case you'd like to verify dotNetify is behaving correctly, enable the developer logging middleware in Startup.cs (requires dotNetify nuget v2.2.x-pre):
app.UseDotNetify(config => config.UseDeveloperLogging());
Using the HelloWorld example, add test property in HelloWorld.cs:
public class HelloWorld : BaseVM
{
public class Person { public string Name { get; set; } }
public Person User { get; set; } = new Person();
...
}
And in HelloWorld.jsx:
var arg = { User: { Name: "Joe" } };
dotnetify.react.connect("HelloWorld", this, { vmArg: arg });
Inside Visual Studio's Output window, check whether the data was correctly received:
[dotNetify] connId=9e2c908f-a0be-41a0-b721-1c42dba5d6d5
type=Request_VM
vmId=HelloWorld
data={"User":{"Name":"Joe"}}
And back in the browser console log, check the server correctly sent the initialized VM data:
from dotnetify.
It doesn't appear the view model is getting instantiated server side. In VS output window I get messages for each of the other view models but the one in question:
The only difference between the RunFeedRow is that it is inside of the RunFeed compoenent:
import React from 'react';
import dotnetify from 'dotnetify';
import { Table, Glyphicon } from 'react-bootstrap';
import RunFeedRow from './RunFeedRow';
class RunFeed extends React.Component {
constructor(props) {
super(props);
dotnetify.react.connect("RunFeed", this);
this.state = { Runs:[] };
}
getInitialState() {
this.vm.onRouteEnter = (path, template) => template.Target = "HtmlResults";
}
render() {
return (
<Table striped bordered condensed hover>
<thead>
<tr>
<th>Run Date</th>
<th>App</th>
<th>Status</th>
<th>Results</th>
</tr>
</thead>
<tbody>
{this.state.Runs.map(run => <RunFeedRow Run={run} />)}
</tbody>
</Table>
);
}
}
export default RunFeed;
Here is the full code for the RunFeedRow:
import React from 'react';
import dotnetify from 'dotnetify';
import { Table, Glyphicon } from 'react-bootstrap';
class RunFeedRow extends React.Component {
constructor(props) {
super(props);
dotnetify.react.connect("RunFeedRow", this, { vmArg: { Run: this.props.Run } });
this.state = { Run: this.props.Run };
}
getInitialState() {
return this.props.Run;
}
render() {
return (<tr key={this.state.Run.Id}>
<td>{this.state.Run.Name}</td>
<td sytle="color: green;">{this.state.Run.AppName}</td>
<td><span>(Pass: {this.state.Run.SuccessfulCount} </span><span sytle="color: green;">Fail: {this.state.Run.FailureCount} Total: {this.state.Run.TotalCount})</span></td>
<td>
<a target="_blank" href={"http://localhost:1881/Runs/" + this.state.Run.Id + "/results"} style={{ visibility: this.state.Run.Finished ? "visible" : "hidden" }} >View Results</a>
</td>
<td><Glyphicon glyph={this.state.Run.Finished ? this.state.Run.Passed ? "ok" : "exclamation-sign" : "hourglass"} style={{ color: this.state.Run.Finished ? this.state.Run.Passed ? "green" : "red" : "black" }} /></td>
</tr >);
}
}
export default RunFeedRow;
Further, I stuck a breakpoint in the config.SetFactoryMethod((type, args) =>{ return container.GetInstance(type); });
func and the RunFeedRow type is never requested.
Any thoughts? Thanks again for the quick answers on these questions.
from dotnetify.
I think the problem was having multiple instantiations of RunFeedRow component, all connecting to the same view model. I suggest refactor to make RunFeedRow purely presentational component; all the data it needs will be passed down by RunFeed.
from dotnetify.
Interesting. So in the dotnetify framework no component that needs a VM can be multi-instance? I actually had it the way you're suggesting at first but when my list grew to about twenty or so items I noticed performance was very lacking. Updates were delayed and sometimes didn't happen at all. I assumed it was from notifying the UI the whole list change when really it was just one particular row, which is why I refactored this way.
Is this a limitation of the current version of dotNetify or React itself? Just curious as I'm very new to both.
from dotnetify.
The CRUD API was specifically created to avoid updating an entire list on individual list item update.
Multi-instance components aren't supported yet in the current version of dotNetify-react. It's already supported in the knockout version, it only needs to be ported.
from dotnetify.
BTW, it's surprising that, even with the entire list update, you would see performance degradation in only 20 list items. React is lightning fast - I've had hundreds of items sent by dotNetify rendered in <1 sec. Perhaps the back-end is sending the update way too frequently?
from dotnetify.
I will try the CRUD API and see if performance is any better that way. The updates were being sent probably once every 1-2 seconds from an external process that was sending results to an API that in turns raises domain events which are subscribed to by the VM. Thanks for all the information! I'll let you know how things go.
from dotnetify.
Cool! A few last things, in the code you pasted: 1) since you're using ES6, getInitialState() will never be called, and 2) if you're planning to dynamically mount/unmount components, connected view model must be disposed on the unmount event (see 'Object lifetime' section in the Overview page).
from dotnetify.
So I refactored things to make RunFeedRow a display only component. I also found out why my Run property was always null which was when my domain model raised the event that was supposed to get sent to it the event was being sent to a new instance of the view model. I've fixed that by putting a singleton "eventHub" in between my API that triggers the domain events and the view models. So now the view models subscribe to events on the event hub and they are being successfully routed to the view model. Now however I'm having a new issue in that even though Changed() and PushUpdates() are being called after properties have been updated in response to the domain updates nothing is updating in the UI. I have developer logging on and I see all of the inital logs to populate the page but no further logs from the updates. Any ideas where I might look now?
Sorry for the rabbit hole. I hope we're close to the end. I feel like I'm so close to having this all work as I need it to!
from dotnetify.
It'll probably be faster if I can see how you wire up all these objects. Can you create a small VS solution that's minimally representative of the design?
from dotnetify.
You can take a look at the actual project, if you'd like. I found that if I registered my view models as singletons some things started to work but very sporadically. It seems something weird is going on with the client. I've seen odd things where if I leave the page open long enough I'll get a javascript error about breaking before running out of memory. Also, if I return a grid of around 50 items and trigger an update it will crash the tab in chrome. I'll try to do some profiling and reproduce the js error when I can.
from dotnetify.
My chart (works on same data source as table) shows up with data in less than two seconds. This grid takes nearly ~38 seconds to render when I allow all ~60 records to come back. I'm wondering if it has something to do with the react-bootstrap stuff I'm using. It is in beta. After lunch I'll try just using a standard table and see if things change.
UPDATE: Removing react-bootstrap had no affect.
from dotnetify.
Here is a profile from chrome: https://www.dropbox.com/s/fmsj9jc41f8qajh/Profile-20170907T115825.json?dl=0
It appears to go nuts rendering the table for some reason
from dotnetify.
Mocked with 50 records with 1 sec timer. Fixed your RunFeedRow to this:
class RunFeedRow extends React.Component {
constructor(props) {
super(props);
}
render() {
return (<tr key={this.props.Run.Id}>
<td>{this.props.Run.Name}</td>
<td style={{color: "green"}}>{this.props.Run.AppName}</td>
<td><span>(Pass: {this.props.Run.SuccessfulCount} </span><span style={{color: "green"}}>Fail: {this.props.Run.FailureCount} Total: {this.props.Run.TotalCount})</span></td>
<td>
<a target="_blank" href={"http://localhost:1881/Runs/" + this.props.Run.Id + "/results"} style={{ visibility: this.props.Run.Finished ? "visible" : "hidden" }} >View Results</a>
</td>
<td><Glyphicon glyph={this.props.Run.Finished ? this.props.Run.Passed ? "ok" : "exclamation-sign" : "hourglass"} style={{ color: this.props.Run.Finished ? this.props.Run.Passed ? "green" : "red" : "black" }} /></td>
</tr >);
}
}
Update seems good now:
from dotnetify.
You should be able to use shouldComponentUpdate. But I'm puzzled why you're seeing lags. I don't see it with the mocked 50 items.
from dotnetify.
Related Issues (20)
- connection disconnected with chrome tab inactive or chrome minimized HOT 3
- Documentation site down HOT 3
- v5.2 no signalr hub connection with older chrome version HOT 3
- Vue 3 sfc setup example
- [Feature] Calling non void method with results HOT 2
- like hubServerUrl in Web API Mode HOT 2
- Coexist React / MVC in the same project. HOT 4
- React and npm packages HOT 3
- Is it required to use AddControllersAsServices? HOT 4
- no $dispatch in vm HOT 1
- Ability to pass multiple arguments to a function $disptach call HOT 4
- async invocation with less repeated code & error handling HOT 2
- Adding IAsyncDisposable to ViewModels
- Request for generic js library HOT 2
- Update NpgSql to lib 7.0.2 in DotNetifyLib.Postgres HOT 1
- The 5.4 version creates several Timeouts without cleaning up HOT 1
- how to get OldRow during an update HOT 1
- Is there a way to set the serverTimeoutInMillseconds setting? HOT 2
- PushUpdates causes all viewmodels of same client instance to push the changes HOT 3
- Replication by dotNetify is missing some inserts
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dotnetify.