Ember nested applications and widgets - javascript

I'm designing the intranet web application for our company. One of the app. requirements is to provide "widget" platform. Which means that developers may create mini application, that will work inside the main web application and can use it's resources. Widgets could be independent of applications and they can have there own data models and behaviors. My task is to provide widget abstraction and widgets engine within application (widgets management and organizing on the application pages). I reviewed several JS "MV*" frameworks and it looks like Ember.js is the thing that I want to use. But I can't understand how to separate in Ember, the abstract functionality between widgets and the application. From one side, the main application is Ember application by itself that manages current widgets appearance, from other, widgets, are applications to. Is it possible to have nested apps in Ember, so can make something like:
Widgets.SpecificWidget1 = Em.Application.extend({
name:"I'm custom widget",
ready:function(){alert('Widget app Ready')}
});
App = Em.Application.create({
rootElement:"#widgetsPanel",
ready:function(){alert('main app Ready')}
});
App.WidgetsController = Em.ArrayController.create({
widgets:[Widgets.SpecificWidget1.create(),
Widgets.SpecificWidget1.create(),
Widgets.SpecificWidget1.create()]
});
App.WidgetsView = Em.View.extend({
});
<div id="widgetsPanel"></div>
<script type="text/x-handelbars">
<ul>
{{#each App.WidgetsController}}
{{#view App.WidgetsView contentBinding="this"}}
<li>{{content.name}}</li>
{{/view}}
{{/each}}
</ul>
</script>
If this way is not correct to do this, can you please tell what is the better way to do it?Thx

It's hard to tell what's happening in the code, but this is my best guess of what you're trying to do. This isn't designed to work as is, but it should put you on the path to what you want to do:
Widgets.SpecificWidget1 = Em.Object.extend({
name:"I'm custom widget",
ready:function(){alert('Widget app Ready')}
});
Assuming this is supposed to be the base model you're working from, the Widget is extending Ember.Object, as that's a tangible thing. As far as I can tell, there's not much to be gained from extending Ember.Application in most use cases, and in a basic scenario where your Ember Application is an entire page, you'll never want more than one.
App = Em.Application.create({
rootElement:"#widgetsPanel",
ready:function(){alert('main app Ready')}
});
App.WidgetsController = Em.ArrayController.create({
widgets : [Widgets.SpecificWidget1.create(),
Widgets.SpecificWidget1.create(),
Widgets.SpecificWidget1.create()]
});
As far as I can tell this is okay.
App.WidgetsView = Em.View.extend({
});
You don't really gain anything from this by itself. If you give it a 'templateName' attribute, you can bind it to a particular template defined in Handlebars to get some functionality, and wrap the general Widget to get a better MVC setup going. But for what you have, you could remove this.
For what I'm working on at the moment, I have a design setup that looks like this Fiddle: http://jsfiddle.net/PastryExplosion/99CMD/

Related

AngularJS module architecture

I am planning to create several modules in my company's application and I'm having trouble designing the architecture for the modules. I have done research and it seems like either you are supposed to use one module per page, or create a 'master' module that depends on all of your other modules. I don't like this approach because it means I have to load all of the javascript for every aspect of my application for every single page. That seems inherently wrong, but I also can't seem to figure out how to handle it the other way if I need to use one module in multiple places on a page. For example, I have a membership module that I have and I'm attaching to the header section of my web page. This would be intended for logging in, registration, and performing a 'forgot password' type workflow.
On another page dedicated to changing a password (from a reset link) the header is also present, but I want to include the password reset functionality in the membership module. I've read that one methodology of designing your application is by functionality/feature. I figured membership was an appropriate application of that, but now I'm not sure since I am having trouble applying the membership module more than once on any particular page.
Am I on the right track, or is there a preferred method for this? Should I have a separate module for the header and one for the rest of the page? Should I just bite the bullet and load everything? (I hope not...)
I should also note that this is an ASP.Net MVC application where we are still heavily relying on MVC for serving views and partial views. As such I wanted to use a render javascript section to dynamically load only the javascript necessary for that page to function. Is this a farce?
<header ng-app="membership">
//stuff for header membership functions
</header>
<div ng-app="membership">
//somewhere else that needs membership, outside of header
</div>
I personally like Mini SPAs (Silos) instead of full SPA. You can watch Miguel A Castro's video, and download the source at his website.
What it does is when a request comes in, it goes to ASP.Net MVC Route first. Then, Angular Route takes over the rest. It is a very slick design.
FYI: Angular 2 is right around the corner, so I went ahead and updated those to Angular 1.5 Compotent so that I can convert to Angular 2 easily later.
If you want, you can stop there. I went one step future, and use Strongly Typed Views using Matt Honeycutt's Building Strongly-typed AngularJS Apps with ASP.NET MVC 5 approach.
Then I implemented Angular Helpers like Axel Zarate's ANGULAR.NET – HELPERS FOR ASP .NET MVC 4.
On an Angular application, as it is a Single Page Application, yes, all your javascript must be loaded. It's the code of your application and it's necessary. That's done only once on first page load.
You're always on the same page, but on a different state.
One good approach is to define a master module who include all other modules. Those modules can also include other "sub modules" they need.
angular.module('App', [
'App.Membership'
// ...
// All others modules you need, including 3rd party modules
])
Then, on each module, you can define the different states associated and their controller
angular.module('App.Membership', [
// Module dependencies
])
.config(['$stateProvider', function($stateProvider) {
//State definition
$stateProvider.state('membership', {
parent: 'app',
url: '/member',
controller: 'MembershipCtrl',
template: '<ui-view/>'
});
}]);
You can also add a global controller to handle elements who are always present, like a header.
Hope this helps

Event-based communication with an AngularJS BackgroundServicesApp on a seperate HTML document

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!

Infrastructure and internationalization for web app(s) using JSON only API

Here is what I intend to build:
There is a service providing data with RESTful JSON-only API. The server setup is Python + Flask.
There are several clients making use of this API, like a normal web app, mobile-compatible client and a Facebook App.
Now, my assumptions/decisions:
I decided on the server providing only data through JSON, thus handing over the presentation completely to the client-side.
I desire to make the web app mobile compatible, thus eliminating need of a separate mobile client.
Also, for Facebook app, I decided to use Facebook Canvas, which would render parts of the normal web app, thus reusing the code.
Feel free to correct me if anything is wrong in above assumptions. Though the above is theoretically possible, I would like to know if the practical implementation is feasible or not.
Now, the web app, after having fetched the base page/template from server, will have to handle the rendering dynamically after fetching data through JSON API. The data is quite simple: multiple-option questions, answering which user receives another question. At the end, user can share the result or invite other users.
With this setup, do I need a framework like angularjs or jQuery would suffice?
My main concern here is how do I handle internationalization? I initially intended to user Flask-Babel to internationalize HTML templates. But having zeroed in on JSON-only API, I don't have a clue as to how/where I handle it now: on client-side or server-side? What are the tools I use for it?
One approach I could think of was to have data in different languages on server itself, and send the JSON response with data in appropriate language, depending on some attribute the client sends in request.
Another approach is to let client do all the translation for a common dataset that server sends. I am not sure of this approach though.
You could find this plugin really helpful.
As far as the usage , it is quite simple to set it up for a single page application that is powered by a JSON API.
If we take a look at a sample usage :
HTML:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="[PATH]/jquery.js" /> // optional
<script type="text/javascript" src="[PATH]/i18next.js" />
</head>
<body>
<ul class="nav">
<li></li>
<li></li>
<li></li>
</ul>
</body>
Json (loaded resource):
{
"app": {
"name": "i18next"
},
"nav": {
"home": "Home",
"page1": "Page One",
"page2": "Page Two"
}
}
JS:
i18n.init(function(t) {
// translate nav
$(".nav").i18n();
// programatical access
var appName = t("app.name");
});
https://github.com/wikimedia/jquery.i18n may be close match. It can handle a lot of languages and messages are in json files and it is complete client side library.
If all of your interface code lives on the client side, so should your i18n. You would use a i18n library that works with the JavaScript framework you are using. For angular, that might be angular-gettext.
If you are developing several client you might use different i18n libraries in different client applications. Try to make sure they all compile gettext .po files – it will make it easier for your translators.
Using jQuery, Angular, etc. is a decision you should make based on your comfort with the technology, the needs of your application, and compatibility with the Facebook Canvas approach. Angular has powerful data binding, but it requires a mind shift compared to jQuery, for instance, so I suggest poking around with each to see if they meet your needs.
As for internationalization, you can use a plugin like jQuery.i18n, or you could roll your own, something I have done with jQuery and jQuery.Mustache for templating. The short version is that you use HTML templates to store your layout, then render them from inside jQuery like so:
var data = {myLabel: 'Some label', myOtherLabel: 'Some Other Label'};
$("#myDiv")
.html( $.Mustache.render( "MyTemplateId", data ) );
in html template:
<script type="text/html" id="MyTemplateId">
<div>
<label for="myInput">{{MyLabel}}</label> <input name="myInput" id="myInput type="text"/>
<label for="myOtherInput">{{MyOtherLabel}}</label> <input name="myOtherInput" id="myOtherInput type="text"/>
</div>
and on your page layout:
<div id="myDiv>
<!-- dynamic content inserted here -->
</div>
You use a loader command with jQuery.Mustache (https://github.com/jonnyreeves/jquery-Mustache) to load your templates from the server, and since you are using templates, you can fill in your values based on user language selection. How you store your internationalized data is dependent on your app. As Michael suggested, if it is a small amount of static content, maybe you just store it all in your JS files as constants and load into your Mustache render() methods as needed. If you have a larger amount/dynamic multilingual content, you should probably store it on the server and load it dynamically. One consideration is the number of languages you plan to support. If you go beyond a handful of languages, consider storing it on the server and loading language data on demand.
I like this approach because it gives you granular, runtime control over your layout and over internationalization. It also stores the data on the server but loads programatically from the client, maintaining a clean separation of concerns for your application layers.
As for responsive/mobile friendly design, using templating (Mustache) and checking the viewport at load time allows you to determine browser capabilities and serve the approrpriate layout without having to prompt the user to select a mobile/desktop experience.
If you go this route, you should also research script loaders like RequireJS and StealJS to handle dependency loading for your scripts, and to handle the initial browser check and layout generation.
Your question is too broad. I can only answer part of it and here are some of the answers:
I desire to make the web app mobile compatible, thus eliminating need of a separate mobile client.
In order to make sure that things are working fine you need to handle
Also, for Facebook app, I decided to use Facebook Canvas, which would render parts of the normal web app, thus reusing the code.
I am not sure.
With this setup, do I need a framework like angularjs or jQuery would suffice?
As you tagged that you are targeting this as a single page application. Therefore, I would recommend you to go for single page frameworks like Anglarjs, knockout.js or Node.js. A quick and good comparison between these frameworks can be found from here
Also this post shares how to implement Internationalization in Angularjs
My main concern here is how do I handle internationalization?
some of these frameworks provide support for handling internationalization and localization natively. For other you can find some links that will help you achieve internationalization.
Whereas if you use jQuery you will to define your own framework for handling single-page-application and apart for that you will need a huge bunch of add-on's to accomplish your objective.
Hope this helps!!!
Steps to implement i18n via js & json:
define css class for i18n tag, e.g. <span class="i18n" id="i18n_username"></span>
define i18n values for different language in different .properties file, e.g. in userhome_en_US.properties, there is a key value: username = Username
write backend API to load .properties file by language, and return in json key-value format, e.g. send param: lang=en_US, page=userhome to I18nAction -> loadI18n(), then it will return json value via ajax: {"username":"Username"},
write js function to load i18n key-value by lang & page param,
update i18n text on web page, by get the tag via css class, and replace content, e.g. use jquery to get all span tag that has class="i18n", then remove the i18n_ prefix of the id, then use it as key to get the value from returned json, then replace the content of span,
I did write util programs like this, it's quite flexible & easy to use. The basic concept is come from struts2 framework's i18n feature.
Although I don't know your technical constraints in detail, I believe it all depends on your volume of data :
If you have few "questions / answers" that probably won't evolve much over time, you can treat I18N as constants. Putting everything on the client side makes sense.
If you have a big amount of "questions / answers" that will probably evolve, I believe you have to treat I18N as data.
Since you have made a JSON API, the odds are that your Q/A is your data, and it already belongs to your server side.
The real question is : do you want to deliver a new version of your client app everytime you add or correct a question?
That's why I would do this :
One approach I could think of was to have data in different languages on server itself, and send the JSON response with data in appropriate language, depending on some attribute the client sends in request.
edit (precision) : I'm talking about the questions and answers. For the application messages (menus, text, help messages, etc), you should use your client framework's i18n components. The other answers provide a lot of good tools.

Using EJS with Ember.js

I wanted to try out some of the new stuff in JS, so I chose to do Node and Ember.js
I have read that Ember.js is agnostic to the templating engine, so I was wondering whether it supports EJS, since that is supported by node, and is quite similar to ERB, what I am used to.
Thanks
You can use Ember views just like Backbone views if you don't want to use Handlebars. However, we did a significant amount of work to make Handlebars templates update automatically when their underlying properties change. Keep in mind that if you use a template engine other than Handlebars, auto-updating (a big part of the appeal of Ember IMO) will not happen.
That being said, you can set the template property of any view to a function that returns a string, and it will render it to the screen.
var view = Ember.View.create({
template: function() { return "Hi there!" }
});
view.appendTo('#container');
If you'd like more details, please see the blog post I wrote on the SproutCore
blog about why we picked Handlebars: http://blog.sproutcore.com/why-handlebars/

Sencha Touch Vs Backbone.js [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What are the basic difference Sencha Touch and Backbone.js, actually have built a project in backbone.js but not aware of Sencha Touch. I have to built a PhoneGap application which one is better for that?
Sencha Touch (our product) is intended to be an all-in-one application framework that provides all the functionality you need to create great looking apps. Everything is designed to work all together on all the major mobile browsers. It's a cleanly architected object-oriented approach to developing apps.
As an "all-in-one" framework, it gives you a full set of resolution-independent UI widgets (carousels, lists, tabs, toolbars, etc. etc.) an MVC library, event management, utility libraries, animation, a theming system, object lifecycle management, a layout system, a drawing and charting library and more stuff than you can shake a stick at... Because it's all designed to work together, the initial learning is higher, but once you're there people swear it's light-years more productive than anything else.
vs.
Backbone.js, which is a simple MVC library. It's about 1,000 lines of code and gives you 5 classes:
Model
View
Router
Collection
Events
It has a dependency on underscore.js for utility functions, so you'll need that too. You will also probably need to use a separate templating library as well as a DOM abstraction/manipulation library like jQuery or jQuery Mobile which also has some UI widgets and a bunch of other libraries to build a full app. But some people prefer to research and hand-curate their individual libraries.
Update: I wanted to add more detail to repond to Ben Bishop's answer below. Aaron Conran, who's our Sencha Architect lead and a Sencha lifer has helped me out with this addition.
There is a definite world view difference between Sencha and backbone. In general, Sencha tends to stay in the JS world and we expect that your JS will generate your HTML content. Backbone on the other hand is kind of a mishmash between an HTML and JS. There's no cut and dry reason to using one or the other, although we believe that data-driven apps of any complexity are better served by the Sencha approach. Ok on to details.
First off re: Classes, Ben's example of declaring a class in JS would put a copy of every property and method in every instance of the object. Typically working in raw JavaScript, you want to put these on the prototype so that they are shared across instances of the class MyClass. The Sencha class system does this automatically for you.
Additionally in raw JavaScript, users have to grok prototypical inheritance correctly in order to properly inherit from or mix in a particular class. Sencha takes care fo thsi without you having to worry.
As far as "magic strings" go (although I'd argue that's a rather negative characterization) you don't have to use them if you don't like them in 4.x , instead you can use Ext.extend with direct identifiers (although this is officially deprecated since 4.0.0 http://docs.sencha.com/touch/2-1/#!/api/Ext-method-extend).
Using magic strings is useful in a few ways.
First off we can worry less about dependency order and when any class is defined/extended from. This matters in complex apps
For example
Ext.define('Turtle', { extend: 'Animal' });
Ext.define('Animal', { });
Works because Sencha waits until the Animal class is defined before defining the Turtle class.
In contrast:
Turtle = Ext.extend(Animal, {
});
Animal = Ext.extend({}, {
});
Does'nt work because we can't find the variable reference Animal.
Second, using strings means we can support dynamic loading. For example if we have
Ext.define('MyApp.foo.MyClass', {
extend: 'MyApp.foo.ParentClass'
});
If you follow a strict class name to JS folder convention, the class loader knows where to load the class namely:
MyApp.foo.MyClass lives in app/foo/MyClass.js
MyApp.foo.ParentClass lives in app/foo/ParentClass.js
This technique makes it easy for Sencha to do useful things:
- The class manager will automatically create proper objects without you having to create & manage namespaces
- Determine the classname of any class or instance
Ext.ClassManager.getName(myInstance) -> "MyApp.foo.MyClass"
Perform some action when a particular class is defined
Ext.ClassManager.onCreated(function() {
}, scope, 'MyApp.foo.MyClass');
Support namespace rewriting, for example if you need to run two versions of the same set of classes concurrently in the same page... you can rewrite the namespace of Sencha Touch's "Ext" top level namespace to something else.
Ok, on to Templates.
In the Sencha templating system, users can embed their templates within any HTML tag that won't muck with it: for example script tags with a custom type (or more typically in Sencha's case a textarea)
var myTpl = Ext.XTemplate.from('theIdOfMyTpl')
You can also store your templates in separate files and load them via an XHR. Though we generally recommend you write something on the server side to manage this for good performance.
re: IDE's
Sencha Architect handles this stuff automatically out of the box (including any places it's referenced in the project, etc). I believe our Eclipse plugin also handles this, but I'd have to check.
Seiryuu is correct. Comparing Sencha Touch vs Backbone.js is like comparing apples and oranges. However, I do want to highlight some differences you will see in developing with either of them.
Before I start, I want to clarify what Backbone is exactly....
Backbone.js is a framework to compliment other libraries like jQuery and/or Zepto. jQuery strengths lie in DOM manipulation not as a macro architecture. Hence why pure jQuery apps tend to be a mess. Backbone provides to traditional web developers the bare bones MVC structure to better organize an app.
To start of my comparison I'm going to start with defining classes...
For example, this is how you declare a class in Javascript:
function MyClass(){
this.myProp1 = 'my value 1';
this.myProp2 = 'my value 2';
this.myMethod = function(myParam){
//do something
}
};
var myInstance = new MyClass();
In Sencha, you declare a class like this:
Ext.define('MyClass', {});
Ext.create('MyClass', {});
Note the heavy reliance on magic strings. However, you could possibly create a make shift enum class with constants that you can use as the class names. Regardless, if you use magic strings for your class names you are going to have a hard time renaming your class 3 or 4 months down the road.
For differences in using HTML...
Traditionally, we declare a form like this:
<form action="/myAction.php">
<label for="username"/>
<input type="text" name="username"/>
<label for="password"/>
<input type="password" name="password"/>
<input type="submit"/>
</form>
In Sencha, you declare a form like this:
{
title: 'Basic',
xtype: 'form',
id: 'basicform',
scroll: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Personal Info',
defaults: {
labelWidth: '35%'
},
items: [{
xtype: 'textfield',
name: 'name',
label: 'Name',
placeHolder: 'Enter Name'
}, {
xtype: 'passwordfield',
name: 'password',
label: 'Password',
placeHolder: 'Enter Password'
}
}]
}]
}
When it comes to templating, in Sencha you define a template like this:
var template = new Ext.XTemplate(
'<p>Name: {name}'</p>',
'<p>Kids: ',
'<tpl for="kids">',
'<tpl if="age > 1".',
'<p>{name}</p>',
'<p>Dad: {parent.name}</p>',
'</tpl>',
'</tpl></p>'
);
template.overwrite(panel.body, data);
With Backbone you have options...
Mustache:
{{items}}
<div>{{name}}</div>
{{/items}}
Or if you need more power jQuery:
<script type="text/template" id="item-template">
<div class="todo <%= done ? 'done' : '' %>">
<div class="display">
<input class="check" type="checkbox" <%= done ? 'checked="checked"' : '' %> />
<div class="todo-text"></div>
<span class="todo-destroy"></span>
</div>
<div class="edit">
<input class="todo-input" type="text" value="" />
</div>
</div>
</script>
With Backbone apps you can either define the templates as inline HTML or load them from external files. I would think you could do the same with Sencha, but I haven't seen any official prescribed methods. Just JS generated HTML strings.
These are just some basic differences between the two at the UI level. With Backbone you can better leverage your existing web skills and knowledge. With Sencha you are learning a complete new ecosystem with its own conventions and quirks.
With the heavy reliance on magic strings (see Sencha form example,) your IDE of choice will probably be limited in what it can do in terms of code completion. Which could possibly lead to slower dev time and a harder time finding bugs created by typos. However, Sencha does offer a Ext Builder app that is supposed to help you build the UI.
When it comes to application infrastructure (Models, Controllers, Services...) Backbone and Sencha are on par with each other. Sencha even has an advantage of sorts with its proxy layer that gives you more flexibility in regards to the integration of your server API, (Backbone is REST heavy.)
When it comes to PhoneGap I suggest you check out XUI. It's jQuery-like library built by the PhoneGap team that is optimized for mobile browsers. If your app is small enough it may not require a full blown app framework.
Hope this helps.
Sencha Touch - a full mobile JS library, along with widgets, animations and all sort of utilities for mobile html5 development.
Backbone - a lightweight library that provides all sorts of utilities for a JS app (structure, models, collections, key-value binding, templating...).
So I don't really see room for comparison here. Both are aimed at different things really. While some of their functionality may overlap, their aim is different. As for developing an app with phonegap and whether to pick Secnha Touch or Backbone - I'd say it depends on the app. I've done Phonegap apps with both - Sencha has a lot of things built in already. In some cases that means faster app development. Other times it might be a hindrance. Backbone gives you basic, non-mobile-specific utilities to build your app. Meaning, writing styles by hand, animations... To sum it up, it depends on the app and your personal preferences/coding style.
Sencha touch gives you a lot of pre-made widgets, but its a lot of work if you want to customize them, or create something "off the beaten path". You end up creating a custom component and digging through lots of layers.
Backbone is more lower-level access and not as "packaged". If you need mobile UI components you can use something like jqtouch - also written by david kaneda, before he went to sencha. not as fully featured, but the basics are there.

Categories

Resources