Giter Site home page Giter Site logo

ki's People

Contributors

colincampbell avatar mlcohen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ki's Issues

Statecharts and SC.routes

I've made a patch to ki to enable adding a "route" hash property to State objects. Based on this property the State init() does SC.routes.add, so the router can trigger gotoState or sendEvent (based on this "route" property).

I've added a setLocation('optional location string') to make easy to set browser location based on the state's "route" property.

Example:
...
rootState: Ki.State.design({

initialSubstate: 'routing',

routing: Ki.State.design({
  // Router will generate the events necessary to go on from here.
}),

// Transient state, determine login status
start: Ki.State.design({
  // Default route
  route: {
    match: ''
  },

  enterState: function() {
    // Set the location to reflect the route to this state
    this.setLocation();
    this.gotoState('loginS');
  }
}),
...

Patch:

diff --git a/frameworks/foundation/system/state.js b/frameworks/foundation/system/state.js
index 927fd5a..5103fab 100644
--- a/frameworks/foundation/system/state.js
+++ b/frameworks/foundation/system/state.js
@@ -92,6 +92,24 @@ Ki.State = SC.Object.extend({
   */
   currentSubstates: null,

+  
+  /**
+    An object that identifies the route belongs to this state.
+   
+    Example:
+    {
+      match: 'users',
+      event: 'showUsers',
+      order: 3
+    }
+    
+    If event is not given, then router will use gotoState
+    instead of sendEvent on the statechart.
+    
+    Lower order routes matched first.
+   */
+  route: null,
+  
   /** 
     Indicates if this state should trace actions. Useful for debugging
     purposes. Managed by the statechart.
@@ -121,6 +139,35 @@ Ki.State = SC.Object.extend({
     return owner ? owner : sc;
   }.property().cacheable(),

+  /**
+    Callback for SC.routes
+    
+    This function gets called if a route that was assigned to this event
+    matches the hash url part.
+   */
+  _handleRoute: function() {
+    var sc = this.get('statechart')
+    if (this.route.event) {
+      sc.sendEvent(this.route.event);
+    } else {
+      sc.gotoState(this.name);
+    }
+  },
+
+  /**
+    Sets browser location
+   
+    Sets the browser location hash part based on the given argument
+    or  - if it's not given - the route propery of the state.
+   */
+  setLocation: function(location) {
+    if (!location) {
+      SC.routes.set('location', this.route.match);
+    } else {
+      SC.routes.set('location', location);
+    }
+  },
   init: function() {
     sc_super();

@@ -138,6 +185,10 @@ Ki.State = SC.Object.extend({
       sc.addObserver(ownerKey, this, '_statechartOwnerDidChange');
       sc.addObserver(traceKey, this, '_statechartTraceDidChange');
     }
+    
+    if (this.route) {
+      SC.routes.add(this.route.match, this, '_handleRoute');
+    }
   },

   destroy: function() {
@@ -1060,4 +1111,4 @@ Ki.EmptyState = Ki.State.extend({
     this.stateLogWarning("No initial substate was defined for state %@. Entering default empty state".fmt(this.get('parentState')));
   }

-});
\ No newline at end of file
+});

'currentStates' property is not observable/bindable

This works:

  valueBinding: SC.Binding.transform(function() {
    return "State: " + App.statechart.get('currentStates').map(function(state) { return state.get('fullPath'); }).join(', ');
  }).from('App.statechart.firstCurrentState')

This does not:

valueBinding: SC.Binding.transform(function(currentStates) {
  return "State: " + currentStates.map(function(state) { return state.get('fullPath'); }).join(', ');
}).from('App.statechart.currentStates')

I would expect currentStates to be observable for changes the same way that firstCurrentState is.

Documentation and example apps?

Will there be a more solid documentation soon on how to use it.

Would be great to read some tutorials and create some example apps.

Could Ki be used with ExtJS?

Hi

I am using ExtJS and really miss the Ki framework.

Is there any change Ki could be used with ExtJS if I include the Sproutcore js files into the frontend?

/Johnny

add default render() implementation in Ki.StatechartManager

render() should be state-aware when Ki.StatechartManager is used in views.

A default render() implementation would dispatch to the view's statechart. (It can easily be overridden by simply implementing render() in the view.)

There are two approaches to dispatching render(). The first (and simplest) is to treat render() like any other actions, and have the deepest state that responds to render() handle it.

The second approach is to walk the hierarchy from root to leaf, in order, giving each state a chance to "render", and then walk it backwards (tags need to be closed). This is more consistent with how states are actually used to render(), and would promote code reuse.

(It would also be nice if, following a state transition, if the state implements render(), if this.displayDidChange() were called automatically.)

Feel free to discuss this further; I'm still working things out (though a solution is necessary).

Why does a state with substates *require* an initialSubstate?

Why can't I have a parent state that happens to have substates but is also itself a full fledged state?

Currently it's like this:

  • CONTACTS - Some dumb parent state

    * SHOW_CONTACTS
    * CREATE_CONTACT - Create contact pane pops up
    * EDIT_CONTACT - Edit contact pane pops up

When I really just want this:

  • CONTACTS - Shows the contacts screen

    * CREATE_CONTACT - Create contact pane pops up
    * EDIT_CONTACT - Edit contact pane pops up

Pass arguments to states?

According to the API I can send arguments to an event:

mainStatechart.sendEvent("showView", sender, context)

But is it possible to send arguments to a state?

this.gotoState("SHOWING_VIEW", fromCurrentState, useHistory)

/Johnny

Send an optional context object along with gotoState

Are there philosophical objections to sending along a context with gotoState that enterState could use? E.g.:

gotoState: function(state, fromCurrentState, useHistory) {

Becomes:

gotoState: function(state, fromCurrentState, context, useHistory) {

Then:

enterState: function (context) {

This would help us simplify a lot of things.

Multiple history states for one state?

I've read your wiki page about history states.

It seems that one state can hold one history state (the substate that was last entered) right?

Is it possible to "log" all states that were entered so it would be like a browser's BACK and FORWARD button, jumping through all states you have been in?

Because now it seems that I can only jump back ONE state.

isCurrentState still not observable

With the latest Ki I must still notifyPropertyChange('isCurrentState') on my state's enterState/exitState to notify things bound to isCurrentState. It appears isCurrentState is still a .property() that doesn't observe anything:

isCurrentState: function() {
  return this.stateIsCurrentSubstate(this);
}.property()

Pass arguments to events and states?

I have set some variables in one state and when i goto another state I want the new state to be able to access the previous set variables.

Is it possible to pass arguments to events and states?

Passing a SC object or string as the second parameter in gotoState()

It seems that it's only possible to pass a hash {} as second argument in gotoState().

If I pass a string or a SC object it says:

"ERROR Ki.Statechart: Can not to goto state Ki.State<session.checkingIfUserIsSignedInAtYi, sc862>. Main.Ki.StateResponse:sc889 is not a recognized current state in statechart"

Is this a bug? It would be good to be able to pass strings, number, arrays but mostly I want to pass a SC object.

Thanks.

gotoHistoryState()

I think the developer does not have to choose between gotoState() or gotoHistoryState(). It is up to the statechart manager to handle that.

Adding two booleans to Ki.state could avoid the use of the method gotoHistoryState() :

A: Ki.State.design({
    initialSubstate: 'A1',
    /** PROPOSAL **/
    history: YES,
    historyRecursive: NO,

    A1: Ki.State.design({
    }),

    A2: Ki.State.design({
    }),
}),

Concurrent states generate duplicate events

Hi, I set a state to have 2 current sub states. When an event happen but is handled by the parent state (not by the sub states), it receive the event 2 times. It would be nice to have an option to deactivate the event forward to the parent state. Let's say a new property named "isFowardingEvent" is NO on a state, it handle the event but do not forward it if the handler method is missing.
In my example, only one of my sub state should have isFowardingEvent set to NO. The other will still forward the event to make sure the parent event receive the event.
Does it make any sense ?

Move states from statechart to views?

Now when you can have states in the view's im wondering when you would want to have them in the views instead of in the statechart.

Eg. I have a TabView with 4 page views ... when I switch page I want to enter that page's state. Is it possible/correct to put those states in the page views instead of the statechart?

This would be kinda like a better approach in my mind, because now my statechart is actually only mirroring the structure of the views and as the application grows it becomes easily unmanageable and I have to play detective and keep the mapping between the statechart and the views hierarchy updated.

It's kinda radical but if I move the whole statechart structure out to the views, this mapping problem seems to be solved. But I would like to know if this is one of the way I should use the new states in the views API for.

initialSubstate: should not be required

The specification does not require an initial substate (you can been in a parent state without being in any substate) and a number of widely used statechart patterns require this behavior.

Ki should allow a state with substates to not define initialSubstate. Currently, it throws an error.

Make isCurrentState et al observable

Right now I can't make a binding to isCurrentState because it's not re-fired once the state does become the current state since it's just a .property().

How to dynamically add states?

I'm using Ki with sproutcore where I'm having a lot of independent modules with their own states.

I wonder how I could dynamically add one module's states in the current statechart?

Thanks.

Ki.State has no method 'get'

While following the documentation in the state chart manager class upon firing up a brand new SC app this is the exception thrown in the console..

currentStates() only returning deepest level of state

While using Master (f410bde) today, we ran into a bug where calling .currentStates() would always return an array of length 1, and the only state being the deepest (not any of the parent states)

Is this expected behaviour? if so, is there a way to get a list of the state tree leading upto the current state? or do I just need to loop through state = state.parentState until I find the one I want?

Go back to previous state?

I have these states:

  • SHOWING_PAGE_ONE
  • SHOWING_PAGE_TWO
  • SHOWING_MENU_PANE

I always enter either SHOWING_PAGE_ONE or SHOWING_PAGE_TWO.

When I enter SHOWING_MENU_PANE and then close it I want to go back to previous state. How do I tell Ki which one of SHOWING_PAGE_ONE and SHOWING_PAGE_TWO was the previous state?

I could of course use currentStates each time I'm in a state and push it to an array to save the information.

But I wonder if there is another way of doing this with Ki? Has this to do with History states?

/Johnny

gotoState(x) when x is the current state shouldn't do anything

I have a simple statechart used for authentication. It has one root state, with multiple substates such as 'loggedIn'.

If the statechart is currently in state 'loggedIn' and i call gotoState('loggedIn'), it runs exitState() and enterState() for the 'loggedIn' state, which seems like the wrong behaviour: if the statechart is already in that state it shouldn't run any state transitions!

This means that in our code, we always have to check that the current state isnt equal to the one we are transitioning to, in order not to run any superfluous transitions.

remove existing Ki.Statechart class and rename Ki.StatechartManager as Ki.Statechart

This won't remove any functionality, but it will allow us to use the Ki.Statechart name where it is most likely to be used: as a mixin on an existing class (especially, views or the main app object in core.js).

The existing Ki.Statechart class behavior can easily be restored with SC.Object.create(Ki.Statechart, {

});

P.s. I'd especially like to see this change made in SproutCore 1.5.

Exception management in statechart.sendEvent()

HI!

statechart.sendEvent is silently handling all exceptions.

      } catch (ex) { /** Gobal the exception and move on */ }

Shouldn't this exceptions be thrown and available for: SC.ExceptionHandler.handleException() to process?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.