Whilst building a Windows Phone 7 app. using the MVVM pattern we've struggled to get to grips with a pattern or technique to centralise navigation logic that will fit with MVVM.
To give an example, everytime the app. calls our web service we check that the logon token we've assigned the app. earlier hasn't expired. We always return some status to the phone from the web service and one of those might be Enum.AuthenticationExpired.
If we receive that I'd imagine we'd alert the user and navigate back to the login screen. (this is one of many examples of status we might receive)
Now, wanting to keep things DRY, that sort of logic feels like it should be in one place. Therein lies my question.
How should I go about modelling navigation that relies on (essentially) switch or if statements to tell us where to navigate to next without repeating that in every view.
Are there recognised patterns or techniques that someone could recommend?
Thanks
It sounds like you have a "state" (something you would switch on) followed by an action (where you would navigate to). There are a number of ways to handle it. One would be to create an INavigationService that exposes the NavigateTo(something) method, where something encapsulates the current state, and the method returns the next state. Perhaps that method would also perform the page swapping itself.
Another way might be to create an IEnumerable that drives the pages, which would make sense in an application driving forward but gets a little fuzzy when you are trying to manage the back button.
With the INavigate, you can push and pop pages (enqueue/dequeue) and then the login would get pushed to the top of the stack and do its thing, then pop the page to return to.
I can't say about specific patterns or techniques, but it looks like you could navigate forward to the login page, not back, when the logon token has expired. If you do the same for all statuses, you will be able to code your status handling logic in one place and call it wherever needed.
Related
After making a post request to add a blog, i then want to display those blogs on the same screen.
So there is no refresh.
What is the best way to get that updated list of blogs. Do i:
make another GET request to get the list of blogs and show a loading bar
just show the posted blog and assume the async POST will be successful
or is there a better way to tackle this?
Thanks
The best tactic really depends on the user experience and your opinion of what the new blog being on the screen might suggest to the user.
For some products, having the page move on immediately, and assuming the back-end is keeping up (eg for dragging a card to another column on a scrum board), will be the most pleasant for the user - no lag, and if the update it didn't go through and the card jumps back, no big issue.
For posting a blog though, a user might expect that if they can see their blog on the website, that that is confirmation of it going through the backend successfully. For that reason I think that another GET request is the better option, as it implicitly confirms to the user a successful POST.
It depends on the rest of your app and what you value.
The first one makes sense if you are using that same back-end controller in another part of your app that shows the blogs (maybe even before the blog is added) and you want to reuse it there.
The second one makes sense if you want to be network efficient and don't mind writing different back-end controllers for different back-end interactions. Also, you don't need to asume it will be successful, you need to catch errors and handle them.
An approach could be to do an empty post that returns the blogs but if the post has a new blog, then it is added and also returns all other blogs.
There is a requirement to make synchronous call out from standard page lay outs of salesfore say for eg. standard case layout. As of my knowledge we can not make a synchronous call out in context to a standard page layout. As process builder or workflow or js button everything will work in an asynchronous context. Want to confirm that , please help with your views.
Erm... no?
Process Builder, Workflow Rule, Trigger - they all fire on event (insert, update). They're all synchronous (the whole operation waits for them to finish saving). Just viewing a record doesn't count as an event. I think you're confusing the "what triggers the action" and "what kind of action happens". Try to distinguish the two. It's like workflows - a workflow rule (condition to be met) is one thing and then what happens (field update, new task, email, outbound message) is completely different thing.
From "clicks not code" functionality Outbound Messages and emails are asynchronous - but as I said above - just viewing a record doesn't count as update, nothing will fire. Callouts done from apex (and you have several options discussed below) can be either synchronous or async. So it's whatever you want really.
You might look into:
a Visualforce page which you'll embed on the page layout (either directly or as a Chatter action for example). That page's apex controller could do the callout.
Or maybe you'd be able to do it in VF from JavaScript (without apex) - make a REST call to your url, process results... There are tons of code samples how to integrate Google Maps for example, this wouldn't be too different.
or (bit of future thinking) make a Lightning Component. You'll be able to embed it in the Lightning App Builder (the "better" page layouts) directly. in Classic SF you'd have to make it a Chatter Action or use "Lightning Out" to reuse a component in a VF page and embed that instead.
Bit more advanced (and paid extra) would be to use Salesforce Connect a.k.a Lightning Connect. Try to pass the Trailhead, easier than explaining it here. You could end up with related list of external records under the case and user wouldn't even realise this data is not hosted in SF. Connect requires OData compatible data source or a piece of Apex that acts as adapter and pretends to return valid format.
If it's about Cases - maybe you can do something fancy using the Service Cloud Console. You'd have to experiment a bit but maybe one of side panels could be a VF page or <iframe> to another system. Maybe you could make something happen with Macros...
I've read a lot of threads here but can't find a real answer.
I'm building a desktop app that first loads a lot of json records (let's call them "cards"). Then the user can filter them down with by using many checkboxes, so he can "sum/substract" options (read: query vars).
I'm also trying to use routes.
So, I can have for example (and I don't really know if I'm doing it the right way):
app.com/#/cards/?near_address=London
app.com/#/cards/?near_address=London&cat=concerts
app.com/#/cards/?near_address=London&cat=concerts&day=8
app.com/#/cards/?near_address=London&radius=10000
[...]
Basically, every time the user change filters, I should add/remove query vars.
I could do it in many ways, for examble using some simple "state" json object, but I'm not sure it would be a good practice, mostly because I'm not really sure if I can instead do it maybe only by using routes (I'm quite new to the routes concept).
Is there any "good practice" in doing this kind of things with backbone?
thank you
Using routes to store state is actually a very good idea. That's what routes are there for, to store state, but it's up to you how granular you would want to go with them. some developers choose to go route per page and some choose to get more granular like your example and that's perfectly fine too. You just have to be careful not to go overboard and make your URLs too long and cryptic.
Using routes to store states gives your a few really important benefits:
Your pages will be refreshable. There is nothing more annoying than refreshing a page and losing all your progress and be take back to the start page of the app.
Your URIs are sharable. I could create a filter see the result and send the uri to anyone and they would see the same page as I was.
They make your life easier as a dev. which goes back to your pages being refreshable, they allow you to change your styles or scripts files and refresh the page and see the updated page without having to navigate through your app to get back to the same view over and over again.
Well, as technology progresses, issues we solved long ago crop up again.
Back in the dark ages, when PHP and ASP were considered awesome, we always had a problem with view states. If you had a page with say a dozen select combo boxes on it, your user chooses some combination and hits next, then realizes they screwed up and hit the back button on the browser, the combo boxes would be back in the default state, usually with option[0] selected. In order to prevent this, we had to write boatloads of boilerplate code that would save the state of those combo boxes to a cookie, or session variable, or something so that when the user hits the back button, we can reload the combo boxes back to the state they were in when they left.
This problem was compounded even further if you had a datagrid on the screen. Because then you would have to come up with some slick way of saving that grid somewhere to prevent from having to hit the database again.
Then came the light. Browser developers realized that most web developers were on the verge of going back to writing terminal programs in Cobol due to this issue and added UI caching to the browsers. This allowed us webdevs to not have to worry about this anymore except in odd situations.
So, life was good. Then someone came up with the bright idea of trying to replicate GWT without all the hassle and the web explodes with all these javascript frameworks. The one im dealing with specifically at the moment is AngularJS 1.2.10 with Angular-UI. I have until Friday (most likely wednesday tho) to make an initial assessment on if this technology is a viable alternative to our current standard (thats pretty much universally hated) JSF.
So, i follow some guides, pound my head against the desk a few times, and I have an angular app with 3 actual HTML pages, each HTML page with 2 views.
Before you go there, understand we can't use it unless we can do multi-page JS apps. Some of the applications that this will be worked into have been in development for a decade or more and its simply not financially practical to scrap an the entire UI and start over again. We would instead be doing things like taking these 50 struts pages and converting them to angular/rest and linking them seamlessly back into the remaining 800 struts pages of the application.
So in my exercise of playing with this, I encounter my old nemesis. Back button view state issues.
I have been playing with the UI-route system. The fact that I can deep link using the route system solves part of my problems. But, if say I have a search page like this:
view-search
combo: search type [member,nonmember]
combo: result type [detail,summary]
combo: search state {all the states]
textbox: contract number
etc etc etc
And various combinations of combo box selections and text entries comes up with a list of 1000 people. Now the user selects one of those people on the data grid and it takes you to view-detail. Well the fact that you can use routing to do something like index.html#detail/bob is cool, but if the user realizes thats the wrong bob and hits the back button, they get a blank search screen again and they have to enter everything over and worse yet, send another search to the database to rebuild the datagrid. Some of these screens have 50 or more options to choose from when searching for data so trying to put all of them into the URL routing sounds completely impractical to me.
Now in my research I found this post:
Preserve state with Angular UI-Router
And that has promise mainly because I have a view state object that I can store into a Redis database or a session EJB for cases when the user actually jumps out of angular and into the legacy Struts application, then back buttons back into the angular application, but the fact still remains that on some of these pages, that is a huge amount of boilerplate code that we would have to write in order to make it work.
I don't really mind the idea of having to manually save off the view state object and read it back in from a Redis server or something anytime a user enters or leaves an HTML page in the system. What i'm really looking for is a way to automatically generate the object that is to be saved without having to write volumes of boiler code.
Is this possible? I keep reading the ui-route documentation but it doesn't look like this is addressed, at least not that i've translated yet.
If this is possible, what controls should I be looking at?
thanks
-------------- Edit
I just thought of something. There is one central scope to each of the single page applications. (Im basically going to be building a multiple single page apps and hooking them together) So if i use a naming convention, something like this
$scope.viewstate.view-search.searchType
$scope.viewstate.view-search.resultType
$scope.viewstate.view-search.searchState
Then the viewstate object should simply be a js array and when I create a function to move to struts.do, i can simply save that array off to the Redis server as a nested map object. Then when my user back buttons back into the angular app, i can capture that using the route system and retrieve that viewstate object from Redis and insert it back into my scope, thereby rebuilding the scope for the entire single page app in one shot.
Would that work?
I believe that you have a very complicated issue of trying to keep the view states between your varying pages with the amount of data in your pages. I think that the only real effective way to do this is to write an angular service that you can then pass to your various pages. as You already know the service is a singleton that you can use in various controllers and could be utilized to maintain the view state as you described. here take a look that this link and see if it will help: http://txt.fliglio.com/2013/05/angularjs-state-management-with-ui-router/
After some thought what you suggest in your edit might work, but I would still use a service to retrieve that array of data, as it would make it easier to reinsert in to angular scope
I am exploring something similar for an Angular app that I am writing. Keeping a user login during a page refresh is easy. Displaying the state on the page after a refresh is an entirely different problem.
How long must the state be persisted? I'm evaluating two possibilities.
First, saving the state (current form values or whatever) to the database. As the page changes, incrementally save the state to the database. On a browser refresh check the database for saved values.
Second is to use local browser storage. This is 5 megs of storage. 5 megs is a lot of text. Again this data would incrementally be saved into storage. When the browser refreshed, simply load data from localStorage.
I'm looking to make a step by step form for an "instant quote" type of thing on my website. I made the following image on photoshop, it's pretty self-explanatory that I want the user to enter information at each step of the form and ultimately submit the form at step 3 (going to the next step should be seamless, without a page reload).
Can someone please give me some general pointers how I should go about this? This is my first project using backbone.js and it would really help to have a high level overview of whats the best way to approach this particular widget.
Thanks
I would structure it as follows:
1. Implement model for data to be collected
Have a single model which collects the data across the stages. Implement storage of this model, and allow partially-completed data. (You'll probably want to store this at each stage, so the user can come back at a later date).
2. Implement a generic 'multi-stage' view
This should be responsible for rendering the tabs/stages at the top, rendering navigation elements for backwards/forwards, and for rendering a sub-view.
3. Implement specific sub-views for each stage
These should operate on bits of the above model.
4. Implement routing
You might want different URL routes for each sub-view, or you might want the same URL for the whole multi-stage process. Either way, the router needs to create the outer multi-stage view and the inner sub-view (or views), and connect them together, together with the appropriate model.
5. Hint: make use of pub/sub
Don't couple your views tightly. Use some form of pub/sub to raise and listen to custom events. (For example: http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/)
To addition to stusmith, I just made an example of a backbone js multistep form. Feel free to have a look and copy it.
https://github.com/michaelkoper/backbone-multistep-form