I'm working on a Sencha Touch app, which currently isn't using controllers. I would like to use Ext.Router to take the visitor to a particular card in a panel. I've seen suggestions that it is possible to use the Ext.Router without using a strict MVC setup. But the example in the API looks like this (see: http://dev.sencha.com/deploy/touch/docs/?class=Ext.Router):
map.connect('dashboard', {controller: 'home', action: 'index'});
Is there a way to, for instance, put a function into map.connect that would show a particular card in a panel?
Second question: is it even worth trying to wrestle with this, or would it be easier to update the app with controllers? (It's a pretty small app in the early stages of development, and would probably have 3 controllers if we went that route.)
I had this same question and was hell bent on not using a controller because I had no time to restructure the code I was given. Like the chosen post reluctantly suggested I used the Ext.History class. If you call this in your onReady function it will activate the myPanel panel with the URL: www.mypage.com/#my-url-slug
function initialiseHistory() {
Ext.History.init();
urlToken = Ext.History.getToken();
if(urlToken == 'my-url-slug') {
Ext.getCmp('tabpanel').setActiveItem('myPanel', false);
}
}
Dirty I know.. but did the job.
The Router is kinda married to the controller and doesn't really provide a way to do what you're asking. If what you're trying to do is show a card based on the URL hash then ya go with a controller cause its trivial to implement.. if you're hell bent on not using a controller for some reason the only thing that comes to mind is Ext.History fires a 'change' event when the url hash changes, you could listen for that event and take appropriate action I suppose.
Related
Preface: I have 1 day of experience playing around with React.
Using this source code from a tutorial, which is set up to login with google. https://github.com/The-Tech-Tutor/spring-react-login
I want to add the "Login with Paypal" button to the Login.js page.
This is what PayPal generates for me.
<span id='lippButton'></span>
<script src='https://www.paypalobjects.com/js/external/api.js'></script>
<script>
paypal.use( ['login'], function (login) {
login.render ({
"appid":"sdfgaesdfgrfed",
"scopes":"openid",
"containerid":"lippButton",
"responseType":"code",
"locale":"en-us",
"buttonType":"LWP",
"buttonShape":"pill",
"buttonSize":"lg",
"fullPage":"false",
"returnurl":"http://localhost:3000/profile"
});
});
</script>
How do I get this third party js to work with React?
Thank you.
I would recommend to take a look at https://developer.paypal.com/docs/log-in-with-paypal/ to get at least a deeper understanding what paypal is doing. I mean second day of react is may be a bit hard to integrate yourself, but as I can't assume your level of knowledge in general about web-dev (front + back) I think this is the way to go. From your code there is nothing suspicious only that you hopefully obfuscated your appId. Otherwise you need to create an appId in your Paypal-Account configure everything correctly (I guess especially the returnurl) and then use the provided appId.
If you only want to migrate the JS files to react look here: https://www.geeksforgeeks.org/how-to-include-an-external-javascript-library-to-reactjs/
I would take the last approach (document.createElement) as is it fully under your control to a certain extent, especially for debugging.
You could also write the whole loader and use implement the paypal.use call inside the react component by using the callback when the script is loaded an then access the paypal.use method.
I'm playing around with NestJs, for the purpose of automating REST API creation as much as possible. So far, I do not see any quick way to create a fully functional resource.
For example, if I use the Nest CLI like this:
nest g resource
And call my resource "posts", I get a module, a controller, a service, dto's and an empty entity
In order to make it functional, I would need to manually go through every method of the PostsService, remove the placeholder, and wire it to the corresponding entity method. For example, this needs to be altered:
findAll() {
return `This action returns all posts`;
}
to:
findAll(){
return this.postsRepository.find()
}
Not to mention, that I need to add various decorators and imports. In my opinion, this undermines the whole idea of CRUD generator. A lot of files are created for me, but they need to be altered.
Is there any way in Nest to create a fully functioning resource(of course i would still need to manually set the fields of the entity), with all parts wired to each other correctly?
I also tried to find something similar. And this is the best what I found https://github.com/ashinzekene/generator-nestjs-app
I think if such a thing existed, then it should have been mentioned in this repository. https://github.com/nestjs/awesome-nestjs
But it's not. Maybe I'm wrong 😑
The purpose of nest isnt to get up and running asap -> You would probably want to use something a little bit more user friendly / or one with a more guided workflow.
in terms of what the generator is giving you...
Controller Only deals with the request / response being recieved and sent... it doesnt have any other type of functionality...
DTO think of it like an interface but with more functionality , as you can add data-validation / etc to make sure the request object is formated properly...
Service Exposes the methods that contain all of our business logic. for a crud app, this would be where your actual get post put patch delete would be ... and how the data us modified in your db. Then once this finishes it would return the response if any to the controller which sends the info out.
this is helpful for many reasons... one if our project has 200 endpoints and 40 people working in different teams you dont want each team to have a different way of doing things, also you want it to be clear where each thing is... if you endpoints need to be changed , you simply go to your controller... if the logic needs to change, you go to that service etc...
The Purpose of nest is to give you a framework for extremely modular apps / essentially everything decoupled..
think of it in terms of an express... you could have a single page express app that just has everything in one place... or you could have every single thing on it's own area...
esentially nest doesnt do anything crazy that express cant, it's just the underlying inversion of control (the .main file which calls the app.module which builds all the different pieces that are needed for that endpoint / app / service / or etc.)
If you just want to use nest because it seems shiny , id consider looking up something like fastify or / even appsmith / or something else like that...
Scenario:
I'm building an AppGyver Steroids mobile web app.
I chose to build a Multi Page Application using multiple WebViews to display parts of my app, because that way I can use native tabs, header bars and page transitions.
My JavaScript framework is AngularJS.
Since every WebView has its own DOM and JavaScript runtime, my AngularJS services are no unique singletons. This creates problems.
Appgyver suggests to load a hidden backgroundServices.html document as an always-there master document and house the singletons in my app there.
They provide a publisher/subscriber method using
window.postMessage("someMessage");
and
window.addEventListener("message", someMethod);
to communicate between WebViews.
Unfortunately they provide no example of this method and I'm really struggling to build a clean implementation.
Since I'm using Restangular I would like my REST services (that should be in backgroundServices) to return promises, and I can't figure out how to do that in a reusable way with a publisher/subscriber mechanism in between, without causing too much overhead..
How can I communicate with an AngularJS service only accessible using Events, and keep working with Promises?
I figure I need to make a "BackgroundServiceConnector" service available on every normal webview.
In this Service I would have a function
call(serviceName, function, parameters)
which I call like this:
var app = angular.module('homeApp', ['ngTouch', 'BackgroundServiceConnectorApp']);
app.controller('LoginCtrl', function ($scope, backgroundServiceConnector) {
$scope.doLogin = function(username, password){
backgroundServiceConnector("accountService", "authenticate", {username: username,password: password})
.then(function(){
//login OK logic
}, function(error){
//login Not OK logic
});
}
});
I think I'm more or less capable of implementing this, but I am unsure of:
how to make this usable for functions that do not return promises. (detect if the function returns a promise at the backgroundServices.html side)
if there isn't a more elegant way in which I don't have to pass "accountService" and "authenticate" as strings.
how I can - in the backgroundServices.html - parse the service name and function into an executable call.
how would I go about making the foreground services automatically "subscribe" to changes in the "model" at the background?
I know enough JavaScript to know it is a very extensible language offering a lot of freedom, but I don't know enough to be able to build a good solution for my scenario..
I would love for someone to help point me in the right direction and provide advice.
Thanks!
In ember.js (I am using 1.1.2) How do I 'send/redirect' a user to a particular url programmatically (without forcefully changing window.location.href).
I have a hybrid application, where we run some legacy code and an Ember "app". In order to make the boundaries really explicit, we created a simply library we called the 'LegacyBridge'. It helps external code call into Ember without having to know too much about the internals. It's also a nice way to limit what external code can do with your Ember App, since there's a lot they could do and it's a good idea to keep limit the options.
Anyway, here's what you could do:
var transitionTo, getContainer;
var getContainer = function() {
return App.__container__;
};
var transitionTo = function(route) {
var router = Ordering.__container__.lookup('router:main');
router.transitionTo(route);
};
this.App.LegacyBridge = {
transitionTo: transitionTo
};
Then somewhere in the non-Ember code:
App.LegacyBridge.transitionTo('posts/1');
This is certainly hacky. In general I wouldn't lookup things directly from the container, but since it's well encapsulate and this is more of an exceptional use case I can live with it.
BTW, this is better than changing the URL, since everything will work even if your router changes the location strategy from history to hash or none, if the rootUrl changes or for browsers not supporting pushState (Ember now will fallback to hash)
Hope this helps.
Check out the guide on redirection.
Ember allows you to transition to a route via it's name or it's URL:
router.transitionTo('post', post)
router.transitionTo('/posts/1')
EDIT:
I'm not sure of a good way to attain a reference to the router from outside your Ember application other than the very discouraged App.container.lookup('router:main'). If you can still handle this UI interaction within your Ember app, it's as simple as adding an action (a method inside the actions hash) to your ApplicationRoute.
Manipulating window.location is probably the 'cleanest' way of triggering a transition from outside your Ember app.
I can't to get a good idea of how you support permalinks. This is perhaps simply because emberjs doesn't support permalinks.
I'm building a UI that allows users to choose certain reports, so in ember this is easy enough you just add a route 'reports' that takes in an id so the URL looks like this:
#/reports/10/
What I need to have is some extra parameters to also be present in that URL for example start and end dates and metric types e.g.
#/reports/10/metric/impressions/start/10-08-2013/end/11-08-2013
So those parameters need to be picked up if I paste them in the browser, AND importantly when the user changes those settings e.g. via a date picker the URL should update to reflect the new parameters.
Edit:
Here is a link to a jsbin with a solution based on the answer below. http://jsbin.com/ucanam/703
Just throwing my 2 cents into this topic. Please note that i am using this approach in production and it works fine. Actually there are 2 parts to this question.
1. How can i have multiple dynamic segments?
One approach is described by Mike Grasotti using nested resources. This approach works but i think this approach is a little bit cumbersome in this case.
Why do i think it is cumbersome?
Routes are a means to separate concerns in Ember. In this case i do not see separate concerns. It looks to me like you are trying to mirror the state of a form in your URL. I think it should be one route that is responsible for the concern "state of the form". Therefore i recommend to have a look at the following post, in which i describe how to implement multiple dynamic parameters per Route: Is resource nesting the only way to enable multiple dynamic segments?
2. How is it possible to trigger the serialize hook to update the URL, when you have changed just one parameter in your form?
The problem is that the serialize hook is only triggered, when the Route gets entered with a new model. I guess you have some logic in place, that deals with the event of changing the parameters start or end. I suppose that you do not re enter the Route in this case. So how do you trigger the serialize hook in this case again to update the URL? I am handling a event like this in my router and there i am using the following code:
var currentRouteName = this.controllerFor("application").get("currentPath");//the ApplicationController stores the name of the current Route
var url = App.Router.router.generate(currentRouteName);
App.Router.router.updateURL(url);
PS: You can have a look at my production app here. This app shows the best movies in cinemas in Germany. Even if you do not know german, you can click on one of the controls in the top area and see the URL getting updated. I guess this is pretty much the same you want?
I have wondered how to do this as well. The data has to go in the URI since we want to share links, but you don't want to confuse the application location with the application state.
The hash: #/reports/10 would be the minimal information required to tell the application where to go. All the other data which is independent of location should probably go in the search portion of the URI. I would suggest something like this:
#/reports?metrics=impressions&start=10-08-2013&end=11-08-2013
In theory you could parse the query string when you enter a route and then update your model accordingly. From my understanding the route's model() function is called when navigating to a route by changing the URL directly or clicking a link so that would be the place.
Unfortunately, in practice this didn't work as I expected. I'm not sure if it's just JSBin, but there is some weird behavior where the link with the extra application data doesn't actually navigate which is the whole point for a permalink. Notice that if you follow the directions in the JSBin the start and end dates are taken from the url instead of the default values. This concept could be extended to send extra requests for different model data using findQuery etc so almost any thing is possible.
http://jsbin.com/abadet/7
Anyways, it might give you some ideas.
There are a couple of ways to get this done in ember. If you need a lot of flexibility for misc parameters that might be passed to a report, check out ember-query which adds query-string support to ember applications.
Another option is to use nested resources. So for example:
App = Ember.Application.create({});
App.Router.map(function() {
this.resource('report', {path: '/reports/:report'}, function() {
this.resource('metric', {path: '/:metric'}, function() {
this.resource('start', {path: '/:start'}, function() {
this.route('end', {path: '/:end'});
});
});
});
});
App.StartEndRoute = Ember.Route.extend({
model: function(params, transition){
return transition.params
}
});
<script type="text/x-handlebars" data-template-name="start/end">
<pre>
Report ID: {{report}}
metric: {{metric}}
start: {{start}}
end: {{end}}
{{log this}}
</pre>
</script>
See this jsbin for working example