Permalink
Browse files

refactorings to and :event

  • Loading branch information...
1 parent fc738c4 commit 50a1f3eec4b53ec5fac82b84d28b0aff42f40dd7 Tobias Bosch committed Oct 13, 2011
View
@@ -3,22 +3,22 @@ Changelog
1.0.3
-------------
-- Bugfix to styling of elements like <a>, ... when used with ng:if (see issue #10).
+- Bugfix to styling of elements like `<a>`, ... when used with ng:if (see issue #10).
- Bugfix for selects with options using `ng:repeat`: If the number of options changed
new values were not displayed be jquery mobile. Was broken by 1.0.2.
- Added a custom style to hide the angular validation popup (the red line around
elements with validation errors still appears).
-- `$activePage` was renamed to `$activate` and does not return the current page any more when
- called with no arguments. Furthermore, it does not more require the pageId to start with a `#`.
+- `$activePage` was renamed to `$navigate` and does not return the current page any more when
+ called with no arguments. It also only takes a single argument in the form ´[transition]:pageId´.
+ Furthermore, it does not more require the pageId to start with a `#`.
If you have to access the current page, use `$.mobile.activePage`.
-- Added `$activate(result, successPage, errorPage)` function in expressions. By this, page navigation can be delegated to the markup,
- and removed from the controllers. E.g. use `ngm:click="$activate(myAction(),'successPage','errorPage')"`.
+- Added `$navigate` function in expressions to move navigation from the controller to the page.
- `ngm:shared-controller` was added to share state between spearate pages
- `onActivate` and `onPassivate` callbacks were removed. Use
`ngm:event="pagebeforeshow:myCallback()"` instead, and `ngm:shared-controller` for sharing sate between pages.
- `ngm:enterKey` was removed. Please use a form with `ng:submit` (and `data-ajax=false`) for this.
- `<input type="range">` did produce two sliders. Bug was introduced in 1.0.2.
-- Added
+- `ngm:event` now expects it's value to be a json string.
The changes to the `$activePage`, `onActivate` and `ngm:shared-controller` was made to have a more general
solution that is also possible for sencha touch applications. By this, applications can easily switch between
View
@@ -108,12 +108,11 @@ If the controller is used on more than one page, the instance of the controller
Note that the shared controller have the full scope functionality, e.g. for dependecy injection
or using `$watch`.
-### Directive ngm:event(event1:handler1,event2:handler2,...)
+### Directive ngm:event({event1:'handler1',event2:'handler2',...})
General event handler that integrates with jquery events, and also with jquery mobile events.
-The value of the attribute has the syntax `<events>:<function expression>,...`. The `events` part may contain one or
-more events (see jQuery bind function). There may be more than one events/function pair in the expression, separated by a komma.
+The value of the attribute is json and defines the event - handler mapping.
-Usage: E.g. `<a href="#" ngm:event="swiperight:myFn()">`
+Usage: E.g. `<a href="#" ngm:event="{swiperight:'myFn()'}">`
### Directive ngm:click(handler)
Special click handler that integrates with jquery mobile's `vclick` event and by this also reacts to touches.
@@ -136,14 +135,12 @@ should be shown via a transition lasting a defined amount of milliseconds (the v
Usage: E.g. `<div ngm:fadein="700">asdf</div>`
-### Service $activate(pageId, transition)
+### Service $navigate('[transition]:pageId')
Service to change the current page.
-
-Parameters (see $.mobile.changePage)
-- pageId: Id of page to navigate to. The special page id "back" navigates back.
-- transition (optional): Transition to be used.
-
-Usage: E.g. `$activate('page2')`
+- If the transition has the special value `back` than the browser will go back in history to
+ the defined page, e.g. `back:hompage`.
+- The transition may be omitted, e.g. `$navigate('homepage')`.
+- To go back one page use `$navigate('back')`.
### Service $waitdialog
The service `$waitdialog` allows the access to the jquery mobile wait dialog. It provides the following functions:
@@ -165,16 +162,19 @@ Default messages are:
Every expression can now use the function `$iff` as a ternary operator:
`$iff(test, trueCase, falseCase)` will return the `trueCase` if the `test` is truthy and the `falseCase` otherwise.
-### Function angular.Object.activate / $activate
-Every expression can now use the `$activate` expression to specify the navigation in the pages.
-By this, the controllers stay independent of the navigation process.
-
-Syntax: `$activate(result, successPage, errorPage)`
-Where result is some result (e.g. that of an action in a controller). If result is not false, this navigates
-to the `successPage`. Otherwise, this navigates to the `errorPage`.
-The result can also be a promise, so that the navigation is not executed until the promise is resolved or rejected.
-
-Alternatively, this can also be used for unconditional navigation: `$activate('newPage')`.
+### Function angular.Object.navigate / $navigate
+Every expression can now use the `$navigate` expression to define the navigation outside of the controlers
+in the html pages. By this, the controllers stay independent of the navigation process and is reusable.
+
+There are two types of syntax:
+1. `$activate(target)`: Navigates to the given target using the `$navigate` service, so the target can also
+ include a transition.
+2. `$activate(test,'outcome1:target','outcome2:target',...)`: Navigates to that target whose outcome equals
+ to the test. The special outcomes `success` is applied for any value for `test` that is not `false` (e.g. also `undefined`),
+ and the outcome `failure` is used for the value `false` of test.
+ This also supports promises. In that case, the navivation is done with the first argument of
+ the `done` / `fail` callback of the promise. Also, the `success` outcome is mapped to the `done` callback
+ and the `failure` outcome to the `fail` callback.
### Paging for lists
@@ -137,67 +137,108 @@ define('jqmng/globalScope',['jquery', 'angular'], function($, angular) {
onCreateListeners.push(listener);
}
+ $.mobile.globalScope = getGlobalScope;
+
return {
globalScope: getGlobalScope,
onCreate: onCreate
}
});
-define('jqmng/activate',['jquery', 'angular'], function($, angular) {
+define('jqmng/navigate',['jquery', 'angular'], function($, angular) {
/*
* Service for page navigation.
- * Parameters (see $.mobile.changePage)
- * - pageId: Id of page to navigate to. The special page id "back" navigates back.
- * - transition (optional): Transition to be used.
+ * target has the syntax: [<transition>:]pageId
*/
- function activate(pageId, transition) {
- // set the page...
- if (pageId == 'back') {
- window.history.back();
+ function navigate(target) {
+ var parts = target.split(':');
+ var animation, pageId;
+ if (parts.length === 2 && parts[0] === 'back') {
+ var relativeIndex = getIndexInStackAndRemoveTail(parts[1]);
+ window.history.go(relativeIndex);
+ return;
+ } else if (parts.length === 2) {
+ animation = parts[0];
+ pageId = parts[1];
} else {
- if (pageId.charAt(0)!=='#') {
- pageId = '#'+pageId;
+ pageId = parts[0];
+ animation = undefined;
+ }
+ if (pageId === 'back') {
+ window.history.go(-1);
+ } else {
+ if (pageId.charAt(0) !== '#') {
+ pageId = '#' + pageId;
}
- $.mobile.changePage.call($.mobile, pageId, transition);
+ $.mobile.changePage.call($.mobile, pageId, animation);
}
}
+ angular.service('$navigate', function() {
+ return navigate;
+ });
+
+ function getIndexInStackAndRemoveTail(pageId) {
+ var stack = $.mobile.urlHistory.stack;
+ var res = 0;
+ var pageUrl;
+ for (var i = stack.length - 2; i >= 0; i--) {
+ pageUrl = stack[i].pageUrl;
+ if (pageUrl === pageId) {
+ var res = i - stack.length + 1;
+ stack.splice(i + 1, stack.length - i);
+ return res;
+ }
+ }
+ return undefined;
+ }
+
/**
* Helper function to put the navigation part out of the controller into the page.
- * @param self
- * @param result
- * @param trueCase
- * @param falseCase
+ * @param scope
*/
- angular.Object.activate = function(self, result, trueCase, falseCase) {
- if (arguments.length===2) {
+ angular.Object.navigate = function(scope) {
+ var service = scope.$service("$navigate");
+ if (arguments.length === 2) {
// used without the test.
- activate(result);
+ service(arguments[1]);
return;
}
- if (result && result.then) {
- result.then(function() {
- activate(trueCase);
- }, function() {
- if (falseCase) {
- activate(falseCase);
+ // parse the arguments...
+ var test = arguments[1];
+ var outcomes = {};
+ var parts;
+ for (var i = 2; i < arguments.length; i++) {
+ parts = arguments[i].split(':');
+ outcomes[parts[0]] = parts[1];
+ }
+ if (test && test.then) {
+ // test is a promise.
+ test.then(function(test) {
+ if (outcomes[test]) {
+ service(outcomes[test]);
+ } else if (outcomes.success) {
+ service(outcomes.success);
+ }
+ }, function(test) {
+ if (outcomes[test]) {
+ service(outcomes[test]);
+ } else if (outcomes.failure) {
+ service(outcomes.failure);
}
});
} else {
- if (result!==false) {
- activate(trueCase);
- } else {
- if (falseCase) {
- activate(falseCase);
- }
+ if (outcomes[test]) {
+ service(outcomes[test]);
+ } else if (test !== false && outcomes.success) {
+ service(outcomes.success);
+ } else if (test === false && outcomes.failure) {
+ service(outcomes.failure);
}
}
};
-
- return {
- activate: activate
- }
+ return navigate;
});
@@ -245,8 +286,7 @@ define('jqmng/waitDialog',['jquery'], function($) {
/**
* jquery mobile hides the wait dialog when pages are transitioned.
- * This immediately closes wait dialogs that are opened in the onActivate
- * function of controllers.
+ * This immediately closes wait dialogs that are opened in the pagebeforeshow event.
*/
$('div').live('pageshow', function(event, ui) {
updateUi();
@@ -311,12 +351,18 @@ define('jqmng/waitDialog',['jquery'], function($) {
});
}
- return {
+ var res = {
show: show,
hide: hide,
waitFor: waitFor,
waitForWithCancel:waitForWithCancel
};
+
+ angular.service('$waitDialog', function() {
+ return res;
+ });
+
+ return res;
});
define('jqmng/event',['angular'], function(angular) {
@@ -325,25 +371,14 @@ define('jqmng/event',['angular'], function(angular) {
* includes taps, mousedowns, ...
*/
angular.directive("ngm:click", function(expression, element) {
- return angular.directive('ngm:event')('vclick:' + expression, element);
+ return angular.directive('ngm:event')('{vclick:"' + expression+'"}', element);
});
- /* A widget to bind general events like touches, ....
+ /**
+ * A widget to bind general events like touches, ....
*/
angular.directive("ngm:event", function(expression, element) {
- var eventHandlers = {};
- var pattern = /(.*?):([^:]+)($|,)/g;
- var match;
- var hasData = false;
- while (match = pattern.exec(expression)) {
- hasData = true;
- var event = match[1];
- var handler = match[2];
- eventHandlers[event] = handler;
- }
- if (!hasData) {
- throw "Expression " + expression + " needs to have the syntax <event>:<handler>,...";
- }
+ var eventHandlers = angular.fromJson(expression);
var linkFn = function($updateView, element) {
var self = this;
@@ -1169,7 +1204,7 @@ define('jqm-angular',[
'angular',
'jquery',
'jqmng/globalScope',
- 'jqmng/activate',
+ 'jqmng/navigate',
'jqmng/waitDialog',
'jqmng/event',
'jqmng/fadein',
@@ -1186,21 +1221,5 @@ define('jqm-angular',[
'jqmng/widgets/jqmSelectMenu',
'jqmng/widgets/jqmSlider',
'jqmng/jqmngStyle'
-], function(angular, $, globalScope, activate, waitDialog) {
- // create global variables
- $.mobile.globalScope = globalScope.globalScope;
-
- // export waitDialog as angular Service
- angular.service('$waitDialog', function() {
- return waitDialog;
- });
- angular.service('$activate', function() {
- return activate.activate;
- });
- return {
- globalScope: globalScope.globalScope,
- activate: activate.activate,
- waitDialog: waitDialog
- }
-});
+]);
})();
Oops, something went wrong.

0 comments on commit 50a1f3e

Please sign in to comment.