Comments (17)
@davidtucker and @ryancampbell were leading this effort, but they are currently tied up with some very exciting (but also very time consuming) client work. Initially, we kicked around some intriguing ideas related to routing (looking at innovative solutions in use on other platforms, such as: https://github.com/jverkoey/sockit). We are discovering that it's particularly difficult to design a routing implementation that scales across both mobile and desktop routing requirements. That said, we haven't given up.
As things stand, routing won't be part of 1.0. I'd like to slate it for the following release. So, we're probably talking a few months from now.
I'd be very interested to hear your opinion of the routing implementations currently available in the Sencha world, i.e. Sencha Touch's routing and Ext.ux.Router. Are there aspects of these solutions that you like or dislike? Considering your real-world application requirements, do either conceptually match your needs or are they too limited?
from deftjs.
I have found out that MVC routing implementation in not an immediate priority for Ext Js even thought it exists in Touch.
With that being said, Ext.ux.Router was created by Sencha professional services team member and was recommended for use. I am currently evaluating it for my project and will report back my experience.
from deftjs.
After trying to make Ext.ux.Router meet my app's requirements, I have decided to remove it. I think the extension is nice, but does not meet some of the required use cases that more complex apps would need. Furthermore, it depends on Ext JS History support which is not utilizing HTML5 History/State APIs. It becomes almost impossible to implement "skipping" on tab panels the user closes, for example. Also, there is very little you can do for redirects unless you modify the code (e.g. trying to pass in model id or similar). I came to the point where I modified the plugin so much, that I realized that I was almost writing something new, instead of just wanting to use routing in my Ext JS MVC app.
from deftjs.
@zam6ak I'm trying to add Ext.ux.Routing... but have some troubles with it.
btw, i found it not so flexible like it could be... so i wanna ask, have you developed your own implementation? Is there other tips?
from deftjs.
@Timopheym No I have not...:(
from deftjs.
In a simple app, the idea of using routing to jump to a specific UI is fairly straightforward. But I'm not really understanding how this would work for a complex app:
Say I have tabs, one of which is for Users. I click on the User tab, pick a record in a grid and click a Show Detail button. This expands a side panel containing the user details. I click edit, and the panel switches to an edit form.
Now, how can someone use a route to jump directly to the user details or user edit form? There are so many prior steps that must be done first (picking the tab, loading the users, selecting one, opening the detail panel, and going into edit mode) that I don't really see how this could happen automatically. To me, it requires a good bit of custom code to perform all of these steps...
from deftjs.
hi,
i don't use DeftJS at all (or Ext or sencha) but i have an interest in IoC containers in javascript and so i watch this project.
http://sourceforge.net/adobe/cairngorm/wiki/HowToUseCairngormNavigation/ describes what i think is a good approach to navigation. i've never used caringorm (or even flex) but the principles outlined there are something i've used in applications and it at least gives one option for how to approach complicated navigation scenarios. maybe it could be useful for you to consider some of the principles used in cairngorm.
from deftjs.
I've used that Navigation library in Flex projects, and it's quite complicated. It looks like adding something like this to DeftJS would be as complex (if not more so) than the entire current functionality of the DeftJS library. So unless my estimation is just way off, we're talking about doubling the size and complexity of the whole library just to add this feature. I'm pretty skeptical on whether it's worth all that work to add this.
I'm wondering if something more basic would work. So if you really need routing, we could parse the URL into a standard structure and hand it to a class/method that the developer writes to handle it. It would be up to them to actually write whatever code is needed to update the UI or load data to actually get the user to the right place in the application.
The other option might be something involving ExtJS's built-in State features, but that relies on cookies and/or LocalStorage. It also looks like that is ExtJS only - looking at the API docs, Touch doesn't appear to have State support.
from deftjs.
Another solution to UI navigation is to use finate state machines (state chart).
Here is an example:
http://stativ.us/
However, the idea behind routing in single page apps is for user to be able to bookmark the url and get to a certain view without navigating.
from deftjs.
The team discussed this problem at length early on in Deft JS's development before abandoning that feature as part of the 1.0 roadmap.
Creating a generalized solution for hierarchical view navigation based on arbitrary routes is extremely difficult. Without enforcing strict rules or conventions on the structure of components that comprise those views and on the format of URLs, creating a generalized solution might well be impossible. Even if we settled on a rigid set of rules to enable this generalized route-aware navigation functionality, as @brian428 said: implementing such as solution would adversely affect Deft JS in terms of size, complexity and flexibility.
What we understand now is that the problem was we were trying to do too much. The key is to avoid conflating A) managing URL state with B) managing navigation state. We can implement a solution for A, but the nature of B will vary for every application and with every development team's unique conventions and preferences.
In a future release (after 1.0), Deft JS will be adding a Router implementation that will make it easy to subscribe to particular URL patterns. It will be focused on managing the browser URL (History API and pushState) and allowing developers to easily observe and react to a particular route being triggered. It will leave the details of updating view state in response to those URL changes to the developer. Simple apps might have a single Router that is instantiated inside their primary ViewController, with routes mapped to methods that know how to modify view state accordingly. More complex applications will likely have multiple common Routers that are injected into key ViewControllers.
Primary influences on the current proposed architecture are:
Our focus is getting 1.0 out the door, but Routing will be one of the first post 1.0 features we will be pursuing.
from deftjs.
For no real reason, I was pondering this tonight and thought I'd see what everyone else thought. My idea is to try and keep this simple on the Deft JS side, while still allowing a developer to supply whatever routing logic is needed for their particular app. I don't really see how all the work could magically be done by Deft itself, since the set of possible actions that are needed to route someone deep into an application are virtually infinite.
Basic Option
So consider a basic setup where a RouteMapper is declared as a dependency:
Deft.Infector.configure(
routeMapper: "MyApp.routing.RouteMapper" #Extends Deft.mvc.RouteMapper
)
When initialized, this class would check the URL for some pattern (possibly customizable as a config option). If the pattern matches, it parses the URL to obtain a "controller name", "action", and any additional parameters. It then attempts to look these up in the route mappings, which might looks like:
routes:
user:
detail: @someHandler
The handler method could be in the RouteMapper, or call another injected object, or call a static method on some other class, or defined inline, etc. However a developer wants to deal with it. It could fire events, create views, call service methods, or whatever else is necessary.
Fairly simple, yet open-ended enough to give people room to do whatever they need to in order to get things set up.
Similar, but a bit more structure...
That said, I also envisioned an expansion on that idea, which is a bit more complex but adds a bit more structure to what happens.
Again, the injector config:
Deft.Infector.configure(
routingEventBus: "Deft.event.RoutingEventBus"
routeMapper: "MyApp.routing.RouteMapper" #Extends Deft.mvc.RouteMapper
)
So same story here: route mapper parses the URL and looks it up in the mapped routes. Say it's controller "user" and action "details". For a given app, this may require switching to a user list tab, populating the list, then selecting a user to open a panel showing the details for that user. So the route mapping could be:
routes:
user:
detail: ( controller, action, params ) ->
flow = [
{ event: "user.list", command: new MyApp.commands.UserListCommand( params ) },
{ event: "user.detail", command: new MyApp.commands.UserDetailCommand( params ) }
]
@buildRouteFlow( flow )
Use of Commands wouldn't be mandatory (the developer can wrap up each "step" however they want to). What's important is the buildRouteFlow
method, supplied by the superclass Deft.mvc.RouteMapper
:
buildRouteFlow: ( flow ) ->
chain = []
for thisStep in flow
chain.push( ( -> @buildPromise( thisStep.event, thisStep.command ) ) )
return Deft.Chain.sequence( chain )
buildPromise: ( event, command ) ->
deferred = Ext.create( "Deft.promise.Deferred" )
@routingEventBus.fireEvent( event, command, ( proceed=true ) =>
if proceed then deferred.resolve() else deferred.reject()
)
return deferred.promise
John can probably see where I'm going with this. Each step in the route flow is wrapped in Promise, and all the steps are fed into a Promise Chain. Each step fires an event, which existing controllers can listen for. The existing controller can make async service calls, create views, etc. Once it's finished with its piece of work, it invokes the passed callback, which resolves that Promise and starts the next one in the chain.
Wrap up
Anyway, that's my (possibly crazy) take on how this could work. The first ("basic") option provides a wide-open gap for people to implement any approach they want to. If a bit more structure is desired, the routing bus and Promise chain option can be leveraged. But even that option isn't particularly complicated. This is really a post-1.0 topic anyway, but I figured I'd post about it since it was fresh in my mind.
P.S. It could get even kookier, where a Pipeline is used instead of a Chain, and each step dynamically determines the next command and feeds it into the next step in the pipeline. But now I'm just talking crazy. ;-)
from deftjs.
Just to add, the creation of the route flow could even be simplified, and Deft could just take the result of the route mapping function and pass it into buildRouteFlow automatically. So at its most basic, something like:
routes:
user:
detail: ( controller, action, params ) ->
return [
{ event: "user.list", command: params },
{ event: "user.detail", command: params }
]
from deftjs.
Hello, I am Juan from Joukou, I will be working on the DeftJS Router task
from deftjs.
Hi, Juan. If you're going to take a stab at this for a pull request, my only advice is to post here with your plan on how this will work and the syntax you propose so that we can discuss and vet it before you spend a lot of time on implementing it.
from deftjs.
Hello Brian,
Ok, I will be posting the plan between today and tomorrow.
from deftjs.
Hello,
The plan for the DeftJS Router is to keep things simple for the first version and then add more features if needed.
The idea will be to have something very similar to BackboneJS giving users the responsability to update the UI for each route.
To create a new route class users will need to extend from "Deft.mvc.RouteMapper", this class will handle the following:
- Listen to history events
- Url matching
- Executing callback functions everytime a url match a configured route
User will decide if they have all their routes in a single RouteMapper class or distributed in multiple ones.
Finally a "Deft.mvc.Router" class will be created, this will be a singleton that exposes basic navigation functions such as:
- goToUrl(url)
- goBack()
- goForward()
In order to use the Router class users will need to require it in the Application file.
In order to initialize every RouteMapper they will need to declare them as a dependency in the injector config.
RouteMapper code example
Ext.define('MyApp.router.MyRouteMapper',{
extend: 'Deft.mvc.RouteMapper'
routes: {
"login": "onLogin"
"user/:userId": "onUserDetail"
"user/:userId/projects": "onUserProjects"
default: "onHomePage"
}
onUserDetail: (userId) ->
#do whatever is needed to render the user details page
.....
})
Please let me know your thoughts.
from deftjs.
Hmm, maybe we can get John to comment. I was leaning more towards the solution I outlined above. What you're showing will technically work, but my worry is that it leaves an awful lot up to the developer to actually implement the "do whatever is needed to render the user details page".
Personally, I'd like to help the developer out a bit more and provide a bit more structure around how the routing works, so it isn't quite so much of a free-for-all.
By defining a built-in routing event bus, we can clearly define the steps involved in each route here in the route configuration, and allow any interested controller to observe the routing bus and do whatever it needs to do. It may also just be me (since I thought it up), but I found the use of a Promise Chain to wrap all the steps a very elegant approach. This would make it very easy for the ViewController handling each step to control when that step is done and allow the next step to start. I think this is important, since the steps will often involve running their own asynchronous processes (service calls, etc.) before the next step can start.
I'll pester John over IM to see if he can comment. (He just LOVES IT when I pester him heh.)
from deftjs.
Related Issues (20)
- DeftJS v0.9 - Promises not working in Internet Explorer 10 HOT 6
- Distribute packages separately. HOT 4
- Update Karma configurations from v0.8 -> v0.10 syntax HOT 1
- Add continuous deployment HOT 10
- Add Ext JS 4.2.2 to the Deft JS Test Suite HOT 2
- Add Sencha Touch 2.3.0 to the Deft JS Test Suite HOT 1
- Update the Test Suite dependencies (Mocha, Chai, Sinon, Promise/A+, etc.)
- Update to Promises/A+ Specification v1.1 and Test Suite v2.0
- Failing to require: the ViewController for a controller: annotation should trigger a warning.
- Sencha Cmd v4.0.0.203 hanging when "requires" : "[email protected]?" added HOT 14
- Migrate back to mixins for Sencha Cmd and Architect compatibility
- Suppress INFO-level log messages when not using the debug build of Sencha Touch HOT 1
- Superclass merging of ViewController 'control:' configurations
- ViewController companions HOT 4
- Touch 2.3.0 coverage report might overwrite 2.2.1 report
- deft.js and deft-debug.js are not in the repo HOT 1
- Sencha cmd 5.0.3 and touch 2.4.1 - build failed HOT 16
- Sencha 2 Routing with Deft JS.. HOT 1
- DeftJS 8.0-9.1Promise/Deferred Memory Usage HOT 5
- Promises catching errors happening in the success method HOT 1
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 deftjs.