Tutorial: Full-stack JavaScript for the Enterprise. Getting started with: Ext JS, Node.js, Express, MongoDB and Docker. (1)

Posted on in Docker Ext JS 6 JavaScript Node JS

This is part I of the tutorial, and covers: JavaScript on the client.

Yeah you are correct, when you have a web project, optimized for production, you can use FTP and simple upload the folder on your server. That’s easy, and when you only have a simple HTML5/JS/CSS app, or an application with a PHP back-end on Apache this probably works fine for you. But what, if you have a very complex application, or you are working on an application with a large team? You probably want to automate as much as possible, and make every live build easy.

This tutorial will show you, how you can create an app where we will use JavaScript on the client (an Ext JS 6 app), and JavaScript on the server (Node.js with Express). Maybe you have played around with Node.js before. When you configured a Node.js app with Express etc, you will probably need to install packages via the the NPM packages manager. These are all dependencies. Now imagine you’ve created on your local workstation a fully working back-end, with Node.js and a MongoDB database. You had to install a lot of packages, and make some configurations on your system. This can be a configuration where you save environment passwords, or maybe even hardware configurations.
What you don’t want, is to manually replicate all the settings and configurations you made locally, again on the server. Ideally, you will take whatever you have on your local machine, and take that over. Maybe you even want to run the same operating system and hardware on production. This is where Docker comes into play.

With Docker you can create an isolated container with all the files such as dependencies and binaries for your app to run, making it easier to ship and deploy. It simplifies the packaging, distribution, installation and execution of (complex) applications.
So, what is an isolated container? These containers are self-contained, preconfigured packages that a user can fetch and run with just a single command via the Docker hub (like Github, but for Docker). By keeping different software components separated in containers they can also be easily updated or removed without influencing each other.

About Docker

With Docker you can create an isolated container with all the files such as dependencies and binaries for your app to run, making it easier to ship and deploy. It simplifies the packaging, distribution, installation and execution of (complex) applications.
So, what is an isolated container? These containers are self-contained, preconfigured packages that a user can fetch and run with just a single command via the Docker hub (like Github, but for Docker). By keeping different software components separated in containers they can also be easily updated or removed without influencing each other.

What you will need:

For this tutorial I used: Ext JS 6 and Cmd 6.0.2, Node.js 5.8 with NPM installed and Docker 1.10.

Please install the following:

Ext JS 6: Create the client app

Create the following folder somewhere on your hard drive: dockerextnode.

Put a temporary copy of the Sencha SDK inside dockerextnode, (for example ext-6.0.2). If you don’t have Ext JS yet, feel free to download the trial: https://www.sencha.com/products/evaluate/

Open Windows Command / Terminal, and navigate on the command-line to the dockerextnode folder. From there enter the following commands:

$ mkdir server
$ cd ext-6.0.2
$ sencha generate app Client ../client

You’ve now created 2 folders. The server* folder, which will contain the Node code later and the **client folder, which contains the copy of the Sencha SDK together with a demo app.

Let’s remove the temp folder:

$ cd ..
$ rm -Rf ext-6.0.2

You’ve now removed the temp. Sencha SDK folder. We can now, start testing our Sencha demo app:

$ cd client
$ sencha app build production
$ sencha app watch

This command will spin off, a Jetty server on http://127.0.0.1:1841. Visit this page in the browser, and confirm you see the Sencha demo app. Once, you’ve seen the demo app, we can stop the server, by stopping the sencha app watch (with CTRL + C for example). We will keep the demo app like it is, but this could be a nice starting point for you, when you want to create your own app.

NOTE:
By default, the sencha app watch command starts the development server on the internal IP at port 1841. If you want to change the server’s port, for example to port 8082, you will have to start the server via the web command. This command will only bootu p an internal server, and won’t “watch” your app for changes. $ sencha web -port 8082 start

Want to checkout all my code? I hosted it on Github:
https://github.com/savelee/docker-ext-client

By the end of this part of the tutorial, you will have a working JavaScript client app, created with Sencha Cmd and Ext JS 6. The next part of this tutorial will cover the setup for creating a Node.js with Express app.*

 

ExtJS6-demo-app

Read the next part

https://www.leeboonstra.com/developer/tutorial-full-stack-javascript-for-the-enterprise-getting-started-with-ext-js-node-js-express-mongodb-and-docker-2/

Native Sencha apps with Ext JS 6 and Cordova / PhoneGap

Posted on in Cmd Cordova Ext JS 6

Last time I played with Cordova, I developed Sencha Touch apps. Been there, done that. Sencha’s new mobile framework, is Ext JS 6. With Ext JS 6 you can create desktop applications or mobile (tablets or phone) apps. And.. you can create universal apps. A universal app, means one Ext JS 6 code base, for any type of device. Whether it’s a phone, a tablet or a desktop app, we let Sencha detect the type of device, browser or OS, and download and serve the right kind of experience for you.
That works great for web applications, the so called PWAs, progressive web apps. But what if you want to create a native app with Ext JS? For example, because you want to sell your app in an app store, or because you want to make use of native device API features. The solution would be Adobe PhoneGap or Apache Cordova.

Just in case you are completely new to this technology; PhoneGap and Cordova are making use of the same technology, but PhoneGap is from Adobe and is a commercial solution, Cordova is Apache and open source. The commercial version has a cloud build tool, which can build your applications to native online, (and therefore you don’t need to install dev tools (like for example XCode) on your own machine. Just like how Cordova works, with PhoneGap it’s also possible to build yourself, from your own machine. This requires you to have the SDKs for Android Dev Tools, Windows Tools or XCode installed on your pc or Mac. The way how Cordova/PhoneGap works, is they will take your web build (the Sencha concatenated / minified JavaScript build, index.html and CSS theme), and copy this in a native project file. (like an XCode project). These SDK project files contain a webview (a native shell. It’s like a browser, it can display webpages/apps, you just can’t enter URLs, it defaults to your web build).

Alright, so in the past I’ve wrote tutorials about Cordova and PhoneGap before, you can find those here and here. However, that has been a while ago, and I’m curious to see if it all works the same way, since technologies change, and so do Android and iOS versions.
In particular I’m curious how it will work with Ext JS 6 universal apps. I do want to have one code base for maintainability, however I do not want to have my desktop application deployed with my mobile app, since it’s only for mobiles. Further more, I don’t want to have my Android interface in an iOS build etc.

So let’s dive into this! We will make use of Cordova, since it’s open source there will be many plugins available.

In case you haven’t already. You will need to install Cordova with the NPM package manager, from your command-line. It requires Node. I’m currently running Node JS version: 5.8.0


$ npm install -g cordova

(Mac OSX users might need to prefix the CLI commands with sudo, for the permissions.)

Afterwards, review if Cordova has been correctly installed:


$ cordova -v

Generate a new Ext JS universal app. (Or use an existing one.)
(sencha generate app MyApp ../mypath), you run this command from the downloaded Sencha SDK folder.

Next open from your Ext JS app, the app.json file. We will add some code here.
Scroll to the “builds” block. Add the following build profile:

    "cordovaios": {
        "packager": "cordova",
        "cordova": {
            "config": {
                "platforms": "ios",
                "remote": false,
                "id": "com.ladysign.Spotifinder",
                "name": "MyApp"
            }
        }.
        "toolkit": "modern",
        "theme": "theme-ios"
    },

The “packager” field, will trigger Sencha Cmd, to make use of your Cordova installation.
Note, you can also enter “phonegap” here, in case you have PhoneGap installed on your machine. Once you have the packager defined, you can use the “cordova” object.
In the “platforms” field, you define the platforms you want to build for (again, it requires the SDK tools for every platform). Unless you are creating an application with one universal look and feel (a theme derived from Neptune or Triton), I would put only one platform here. You can always create multiple build profiles in the app.json. I only wrote “ios” here, because my app is making use of the new Ext JS 6.2 “theme-ios” theme. (Remember, that I don’t want to put more than one theme in my build?). The field “remote” is set to false, unless you want to make use of the PhoneGap cloud builder, than it would be “true”. The “id” is the id (reverse domain notation), you will use in your app store, and “name” that’s the name of your app, as you use in Ext.Application.
The “toolkit” property is important for an Ext JS 6 app. (Remember, that I don’t want to include the desktop version of my app in this build?). All phone applications should make use of the toolkit, since that’s a faster performing toolkit, with more components that were designed for mobile touch user experience.

Next. verify, that you didn’t make typos in the app.json file, by running from your project folder the following command:
$ sencha app refresh

Now, we need to modify the index.html file, to make sure the application can load within Cordova. The microloader will need to detect if it’s an Cordova app, to load the correct JavaScript code and theme:

    var Ext = Ext || {}; // Ext namespace won't be defined yet...
    // This function is called by the Microloader after it has performed basic
    // device detection. The results are provided in the "tags" object. You can
    // use these tags here or even add custom tags. These can be used by platform
    // filters in your manifest or by platformConfig expressions in your app.
    //
    Ext.beforeLoad = function (tags) {
        var s = location.search,  // the query string (ex "?foo=1&bar")
            profile;
        if (
            location.href.match(/\bcordova\b/) ||
            Ext.platformTags.cordova ||
            Ext.platformTags.webview
        ) {
            profile = 'cordovaios';
        }
        else if (s.match(/\bmodern\b/) || tags.ios) {
            profile = 'modern';
        }
        else if (s.match(/\bandroid\b/) || Ext.platformTags.android > 0) {
            profile = 'android';
        }
        else {
            profile = 'classic';
        }
        Ext.manifest = profile;
    };

Note the:
if (location.href.match(/\bcordova\b/) || Ext.platformTags.cordova || Ext.platformTags.webview)

This tells the Sencha microloader, to load the “cordovaios” build, if: “cordova” is in the url (to test on your development machine) or if the app runs in a cordova or webview shell.
Sure, instead of all this if else checking, you could force Ext.manifest = ‘cordovaios’ but the magic here, is that we will reuse this index.html for every type of app, whether it’s an desktop app, iOS PWA or Android PWA. So this microloader is actually great.

Ready? Let’s go and build:

$ sencha app build cordovaios

We tell Sencha Cmd to build the “cordovaios” profile, like we wrote in app.json.

Woopie. It seems like it worked. Let’s take a close look and see where the build is located.
According to my build log, it looks like there’s a cordova folder created in my Ext JS application folder:

MyApp/cordova:

MyApp
- cordova
- - config.xml
- - hooks
- - platforms
- - plugins
- - www
- - - index.html
- - - cordovaios
- - - - app.js
- - - - resources
- - - - - MyApp.css

The www folder, will be the place, where a copy of your Sencha Ext JS 6 app will be located. Let’s look into this folder, and verify what’s inside of it.

So what’s in the cordovaios folder, is the JavaScript code, for the modern toolkit only. Nice!
So. you won’t bundle the desktop version inside of it. And also, it only includes one theme, the right one. This is all because of the “toolkit” and “theme” settings we made in the app.json file.
How awesome.

Let’s cover some Cordova / XCode stuff, since you are here anyway. If you have done this before, this is probably not so interesting for you…

Oh cool. So you are still here.
Open config.xml and modify the name and description fields to describe your app.

After your first build, you can copy the generated cordova.js and cordova-plugins.js files, and put it in your cordova www folder. Copy it from MyApp/cordova/platforms/ios/www. That way the other cordova/www folder won’t have 404 errors.

You could make another build:
$ sencha app build cordovaios

Open your application from the cordova www folder in your browser, and verify that everything works without issues. For example:
http://localhost/MyApp/cordova/www/

We don’t need the auto generated css and js folders. So remove those.
No worries, the next time you make a cordovaios build, those folders won’t come back.

Ok, so basically, we could now open XCode, open the MyApp/cordova/platforms/ios/MyApp.xcodeproj, and build with XCode tools, the applications.

In XCode, press the “play” button. It creates a build, and it should run it in an simulator. I run into a common issue:

“The status bar is mixed into my layout.” We can fix this with the cordova-plugin-statusbar plugin. So install it.

Run on the CLI from he cordova folder:
$ cordova plugin add cordova-plugin-statusbar

Add to config.xml the following configuration:


In XCode rightclick your project to view the resources/MyApp.pList configuration. And add the following settings:

Status bar is initially hidden = YES
View controller-based status bar appearance = NO
UIRequiresFullScreen = YES

This should be fixed. Next replace all the Cordova logos and splash screens. You can find and replace those assets from here:
MyApp/Cordova/platforms/ios/MyApp/Images.xcassets

And that’s it. Project > Clean your build, Rebuild, “Project > Build”. And test and run your application in the simulator.

For iOS developers, the next steps would be to setup an paid Apple Developer account. It cost about a 100 bucks a year, and you can sell unlimited applications from the Apple App Store.
With the developer account, you can get access to iOS beta releases, and you can test your applications on real devices.

https://developer.apple.com/

Success! Feel free to share your deployed Sencha hybrid apps for Android or iOS with me in the comments!

How to Upgrade a Sencha Touch App to Ext JS 6 Modern Toolkit – Part 1

Posted on in Ext JS 6 Sencha Touch
Cupertino Theme

Previously, I wrote a blog post on how to create great looking universal apps with Ext JS.
However, we also have lots of customers who currently have a mobile (phone or tablet) application and want to upgrade it to Ext JS 6.

In this tutorial, I will show you how you can upgrade your app, and why you should consider taking this step.

I used my existing tutorial files, “Do I need my umbrella” weather application, which I wrote a couple of years ago with Sencha Touch 2. You can find the original tutorial here. You can download the tutorial files here.

You don’t have to use these tutorial files, you can also just read through this guide and try it out with your own existing Sencha Touch 2 app.

Ext JS 6 Modern Toolkit and Sencha Touch

Ext JS has more (advanced) classes and features than Sencha Touch. You can create advanced enterprise desktop applications, and now you can also create advanced mobile applications or even advanced cross-platform apps.

We incorporated concepts from Sencha Touch 2, and merged them as “the modern toolkit” in Ext JS 5, with the modern core (class system, mvvm pattern, etc.), and there are also many updated classes. From a theming perspective, Ext JS 6 modern toolkit has been updated and looks different than Sencha Touch.

When you’re looking for an enterprise solution to create mobile apps, whether it’s a universal app or just mobile, there are many reasons why you’d choose Ext JS 6 Modern toolkit. I will explain these benefits to you in this article.

Then, I will take an example Sencha Touch 2 application, and migrate it to Ext JS 6 with the Ext JS 6 Modern toolkit.

What’s Different in Ext JS 6 Modern Toolkit

Here’s an overview of new features in Ext JS 6 compared to Sencha Touch.

Basic Upgrade

(No change to the MVVM pattern)

This upgrade allows you to use:

  • the latest mobile framework version, and support for the latest OS & browser versions
  • running your mobile application on your desktop computer too
  • controlling lists with your mouse scroll and keyboards (besides touch support)
  • new packages / theme packages structure
  • new Neptune and Triton (universal) themes
  • fast theme compilation with Fashion
  • cleaning up your models, by writing less code
  • JavaScript promises, for asynchronous code
  • out-of-the-box font-awesome integration
  • one of the new components/classes:
    • data grid
    • data tree
    • navigation tree list
    • soap, amf0, amf3 proxies
    • new charts
    • form placeholders

Advanced Upgrade

(Change to MVVM architecture pattern)

This upgrade allows you to use:

  • ViewControllers and ViewModels
    • The Stores and Controllers in MVC are global. VCs and VMs live together with a particular view, which means that they will be created with a view, and can be destroyed. ViewModels and ViewControllers therefore can improve your application performance. They also allow you to write less code and make it easier to maintain.
  • Databinding
    • Bind to data or component states. It allows you to do advanced things by writing less code.

Universal Upgrade

This upgrade allows you to:

  • Create cross-platform apps, for mobile phones and tablets, but also desktop computers. By supporting the modern (lightweight component set) and the classic rich desktop component set.
  • Support legacy browsers, like Internet Explorer 8, as well as the latest modern (mobile) browsers.

Things That Changed in the API

You can read a complete list of Ext JS 6 API changes here. The ones that I faced when upgrading the weather utility app are:

  • ViewControllers and ViewModels
    • The Stores and Controllers in MVC are global. VCs and VMs live together with a particular view, which means that they will be created with a view, and can be destroyed. ViewModels and ViewControllers therefore can improve your application performance. They also allow you to write less code and make it easier to maintain.
    • Sencha Touch has Ext.app.Controller.launch() methods; in Ext 6 Modern toolkit, it’s Ext.app.Controller.onLaunch()
    • In Sencha Touch, you had to define everything in a config block; in Ext 6 Modern toolkit, you just put properties in config blocks that need the magic methods (get, set, apply, and update). Although you don’t have to, you can clean up the config blocks.
    • There are changes in the way you wire up stores that you can read about in these docs:
    • Sencha Touch validations are now called validators
    • The Sencha Touch default theme was replaced by Ext JS 6 Modern toolkit themes – Neptune and Triton.
    • The default icon set that is being used is Font Awesome, instead of Pictos.

    Basic Mobile Upgrade

    For the basic, easy upgrade, we will stick with the existing MVC pattern. You will see that it won’t take many steps. However, you won’t be taking advantage of Ext JS 6. You will have the latest framework, with all its features and classes, but you won’t be using the new MVVM pattern.

    1.  Download the Ext JS 6 (trial version).

    2.  Look in your Sencha Touch project (app.js for example), and note the namespace that was used. For example, for the Weather Application, the namespace is “Dinmu”.

    3.  Generate an Ext JS 6 modern app:

    Navigate to the ext framework folder, and generate a project with:
    sencha generate app -modern
    For example:
    ext> sencha generate app -modern Dinmu ../dinmu1

    See https://github.com/savelee/ext-weatherapp/tree/master/dinmu1

    4.  Go to the project in your browser, you should see the new Ext JS 6 demo app.

    5.  In your file system, rename the <myproject>/app folder to something else (like app-backup)

    6.  Do the same for the app.js file; rename it to app-backup.js

    7.  Then, copy the app folder and the app.js from your Sencha Touch project, and paste it in your new Ext JS 6 project.

    In case you are loading external JS or CSS files via app.json, you can manually merge those lines into the new app.json. My advice is to do these kind of steps at the end, after you have your app running.

    8.  Run the following command from the command-line:

    1. sencha app refresh
    2. You might run into build errors here, because of API changes. For the Dinmu app, there was an error because Ext.device.Geolocation has been deprecated.
    3. When you have lots of custom components, you may run into problems here. The best way to solve them is to read the messages from the CLI, and open the Modern toolkit API docs to search for the classes that fail. In my case, it was the geolocation class that failed. In the docs, I noticed that there are no device APIs anymore. In Sencha Touch, these classes where wrappers for PhoneGap/Cordova support, that would fall back to the HTML5 API feature, if available in the browser. There is Ext.util.Geolocation, so I changed the code to use it. After I changed the line, I ran another sencha app refresh again, to check for more errors. See the results here.

    9.  When you don’t have any more errors anymore, you can try to run the application in the browser. When I ran my app, I got a console error in my app.js launch method.
    Ext.fly(‘appLoadingIndicator’).destroy();

    Basically, this is an error that tells you that you can’t destroy the “appLoadingIndicator” element, just because it’s not there. The index.html is just different. Now you don’t want to replace the index.html file, with the Sencha Touch one, because the calls to the microloader are different. It’s up to you, if you want to remove this destroy line in the app.js launch method, or if you take over the <style> and <body> tags from the Sencha Touch app. I liked the Sencha Touch simple CSS preloader, that you will see before loading any JS or CSS, so that’s why I took over those tags. After fixing this problem, I was able to open my Ext JS 6 app in the browser.

    10.  The application is running a bit odd. By inspecting my application, I noticed that in my Sencha Touch application I have controllers with launch methods. And launch methods on controllers don’t exist in Ext JS 6, instead they’re called: onLaunch. So I renamed it, and ran the application again.

    11.  This time I had a problem with the store. The store manager couldn’t find Ext.getStore('Settings'), because it was wired up to the controller like this: Dinmu.store.Settings. Instead, the store manager has to access it via the full class name. I fixed it in the controller, instead of wiring up the full path, and I just passed in the Store name.

    12.  The settings button was not visible; this was due the changes in the icon sets. I used the default font-awesome settings icon, and changed the iconCIs in the Settings button in Main.js to: x-fa fa-cog

    Settings

    13.  Last step was to run a build to make sure that I was able to build my application. I expected it to work, because the sencha app refresh command did not fail.

    And that’s it. After this last step, I was able to run the Weather Application as a full working Ext JS 6 mobile app.

    Coming Up Next

    In the next article in this series, I’ll show you how to do the advanced upgrade, where we will switch to the new MVVM pattern, and we can also clean up some code.

Which OS and browsers do Ext JS 6 support?

Posted on in Ext JS 5 & 6 Ext JS 6 Questions

Operating System

In theory, every desktop OS. - but it’s probably best to look which operation systems are supported by Sencha Cmd, since this one has an installer. (Mac OS X, Win 32, Win64, Linux 32)

https://www.sencha.com/products/extjs/cmd-download/

Supported Browsers

Classic Toolkit Desktop:

  • IE8+ (Strict DOCTYPE)
  • Firefox and Firefox ESR (Latest 2 Versions)
  • Chrome (Latest 2 Versions)
  • Safari 7+
  • Opera (Latest 2 Versions)

Classic Toolkit Mobiles:

  • Safari 7+ (iPad)
  • Android 4.0+ Chrome
  • Android 4.4+ Native
  • Windows 8 Touch Screen - IE10+

Modern Toolkit Desktop:

  • IE11+
  • Firefox and Firefox ESR (Latest 2 Versions)
  • Chrome (Latest 2 Versions)
  • Safari 7+

Modern Toolkit Mobile:

  • IE11+ (Windows Phone)
  • Safari 7+
  • Android 4.0+ Chrome
  • Android 4.4+ Native

Not mentioned, but it's supported for Sencha Touch, hence why I think it's included in Modern Toolkit mobiles as well:

  • BlackBerry browser
  • Tizen browser

How can I get started with Sencha?

Posted on in Ext JS 5 & 6 Ext JS 6

This link, might be helpful:

How to embed an Ext JS 5+ app in a div on an external app/website

Posted on in Ext JS 5 & 6 Questions

Sometimes, you would need to embed Sencha applications into an existing portal or CMS.
(Please note, often this requires an OEM license).

Since Ext JS 5 is mainly focussed on creating single page apps, this can be a tricky thing to achieve.
There are a couple of solutions you could look into.

  • 1) Using Ext.onReady() in combination with loading ExtJS-all.js. This is the way how Sencha prototypes examples in the API docs.
    It works. - But it's hard to re-use, hard to theme, and no use of Sencha Cmd.
  • 2) Using an iframe.
    For sure, the most easy solution but it's an iframe.
  • 3) Using the multiple apps approach.
    This should be the preferred Sencha way. But note, the Ext JS viewport takes over the entire screen.

The last solution could be the ideal solution. See the Sencha guides to read more about this:

http://docs.sencha.com/cmd/5.x/workspaces.html
http://docs.sencha.com/cmd/5.x/advanced_cmd/cmd_multi.html

Since the multiple apps approach uses the Sencha viewport, the viewport will take over the entire screen, which can be something what you don't want.
Unfortunately there is no out of the box solution to embed Sencha applications into div elements.

There are 2 things you can do.

1) Override the Ext.plugin.Viewport to let it embed in HTML elements.
2) Insert the HTML parts into a Sencha Component to let it be part of a Sencha layout.

Rendering the viewport in an HTML div element.

This approach would require you to override the viewport plugin.

/**
 * This plugin can be applied to any `Component` (although almost always to a `Container`)
 * to make it fill the browser viewport. This plugin is used internally by the more familiar
 * `Ext.container.Viewport` class.
 *
 * The `Viewport` container is commonly used but it can be an issue if you need to fill the
 * viewport with a container that derives from another class (e.g., `Ext.tab.Panel`). Prior
 * to this plugin, you would have to do this:
 *
 *      Ext.create('Ext.container.Viewport', {
 *          layout: 'fit', // full the viewport with the tab panel
 *
 *          items: [{
 *              xtype: 'tabpanel',
 *              items: [{
 *                  ...
 *              }]
 *          }]
 *      });
 *
 * With this plugin you can create the `tabpanel` as the viewport:
 *
 *      Ext.create('Ext.tab.Panel', {
 *          plugins: 'viewport',
 *
 *          items: [{
 *              ...
 *          }]
 *      });
 *
 * More importantly perhaps is that as a plugin, the view class can be reused in other
 * contexts such as the content of a `{@link Ext.window.Window window}`.
 *
 * The Viewport renders itself to the document body, and automatically sizes itself to the size of
 * the browser viewport and manages window resizing. There may only be one Viewport created
 * in a page.
 *
 * ## Responsive Design
 *
 * This plugin enables {@link Ext.mixin.Responsive#responsiveConfig} for the target component.
 *
 * @since 5.0.0
 */
Ext.define('Demo.override.plugin.Viewport', {
    override: 'Ext.plugin.Viewport',

    alias: 'plugin.viewport',

    /**
     * @cfg {Number} [maxUserScale=1]
     * The maximum zoom scale. Only applicable for touch devices. Set this to 1 to
     * disable zooming.  Setting this to any value other than "1" will disable all
     * multi-touch gestures.
     */

    setCmp: function (cmp) {
        this.cmp = cmp;

        if (cmp && !cmp.isViewport) {
            this.decorate(cmp);
            if (cmp.renderConfigs) {
                cmp.flushRenderConfigs();
            }
            cmp.setupViewport();
        }
    },

    statics: {
        decorate: function (target) {
            Ext.applyIf(target.prototype || target, {
                ariaRole: 'application',

                viewportCls: Ext.baseCSSPrefix + 'viewport'
            });

            Ext.override(target, {
                isViewport: true,

                preserveElOnDestroy: true,

                initComponent : function() {
                    this.callParent();
                    this.setupViewport();
                },

                handleViewportResize: function () {
                    var me = this,
                        Element = Ext.dom.Element,
                        width = Element.getViewportWidth(),
                        height = Element.getViewportHeight();

                    if (width != me.width || height != me.height) {
                        me.setSize(width, height);
                    }
                },

                setupViewport : function() {

                    var me = this,
                        targetEl = me.renderTo,
                        el;

                    if(targetEl){
                        el = me.el = Ext.get(targetEl);
                    }
                    else {
                        el = me.el = Ext.getBody();
                    }

                    // Get the DOM disruption over with before the Viewport renders and begins a layout
                    Ext.getScrollbarSize();

                    // Clear any dimensions, we will size later on
                    me.width = me.height = undefined;

                    // Andrea: Need to comment this
                    //Ext.fly(el).addCls(me.viewportCls);
                    el.setHeight = el.setWidth = Ext.emptyFn;
                    el.dom.scroll = 'no';
                    me.allowDomMove = false;
                    me.renderTo = el;

                    if (Ext.supports.Touch) {
                        me.initMeta();
                    }
                },

                afterLayout: function(layout) {
                    if (Ext.supports.Touch) {
                        this.el.scrollTop = 0;
                    }
                    this.callParent([layout]);
                },

                onRender: function() {
                    var me = this,
                        el = me.el;

                    me.callParent(arguments);

                    // Important to start life as the proper size (to avoid extra layouts)
                    // But after render so that the size is not stamped into the body
                    me.width = el.getWidth();
                    me.height = el.getHeight();

                    // prevent touchmove from panning the viewport in mobile safari
                    if (Ext.supports.TouchEvents) {
                        me.mon(el, {
                            touchmove: function(e) {
                                e.preventDefault();
                            },
                            translate: false,
                            delegated: false
                        });
                    }
                },

                initInheritedState: function (inheritedState, inheritedStateInner) {
                    var me = this,
                        root = Ext.rootInheritedState;

                    if (inheritedState !== root) {
                        // We need to go at this again but with the rootInheritedState object. Let
                        // any derived class poke on the proper object!
                        me.initInheritedState(me.inheritedState = root,
                            me.inheritedStateInner = Ext.Object.chain(root));
                    } else {
                        me.callParent([inheritedState, inheritedStateInner]);
                    }
                },

                beforeDestroy: function(){
                    var me = this,
                        root = Ext.rootInheritedState,
                        key;

                    // Clear any properties from the inheritedState so we don't pollute the
                    // global namespace. If we have a rtl flag set, leave it alone because it's
                    // likely we didn't write it
                    for (key in root) {
                        if (key !== 'rtl') {
                            delete root[key];
                        }
                    }

                    me.removeUIFromElement();
                    me.el.removeCls(me.baseCls);
                    Ext.fly(document.body.parentNode).removeCls(me.viewportCls);
                    me.callParent();
                },

                addMeta: function(name, content) {
                    var meta = document.createElement('meta');

                    meta.setAttribute('name', name);
                    meta.setAttribute('content', content);
                    Ext.getHead().appendChild(meta);
                },

                initMeta: function() {
                    var me = this,
                        maxScale = me.maxUserScale || 1;

                    me.addMeta('viewport', 'width=device-width, initial-scale=1, maximum-scale=' +
                           maxScale + ', user-scalable=' + (maxScale !== 1 ? 'yes' : 'no'));
                    me.addMeta('apple-mobile-web-app-capable', 'yes');
                },

                privates: {
                    // override here to prevent an extraneous warning
                    applyTargetCls: function (targetCls) {
                        this.el.addCls(targetCls);
                    },
                    
                    // Override here to prevent tabIndex set/reset on the body
                    disableTabbing: function() {
                        var el = this.el;
                        
                        if (el) {
                            el.saveChildrenTabbableState();
                        }
                    },
                    
                    enableTabbing: function() {
                        var el = this.el;
                        
                        if (el) {
                            el.restoreChildrenTabbableState();
                        }
                    },

                    getOverflowEl: function() {
                        return Ext.get(document.documentElement);
                    }
                }
            });
        }
    },

    privates: {
        updateResponsiveState: function () {
            /* Andrea: Need to comment this for now, otherwise stretching In and Out
             * the browser will make the viewport full screen again. */
            //this.cmp.handleViewportResize();
            //this.callParent();
        }
    }
},
function (Viewport) {
    Viewport.prototype.decorate = Viewport.decorate;
});

The app.js should disable the autoCreateViewport, and in your app launch method, you should create the main interface like this:

Ext.create('MyApp.view.main.Main',{
   requires: ['Ext.plugin.Viewport'],
   renderTo: 'mydiv',
   plugins: [{
    ptype: 'viewport'
   }]
});

Please note, this is just a quick code example, I'm not sure if it's 100% functional.

Rendering contents in the viewport

As an alternative to the viewport take over, and rending the contents in a div. You could also render the HTML parts in the viewport. (so the otherway arround).

Such an example can be found in the Ext JS 5 example apps:

http://dev.sencha.com/ext/5.0.1/examples/calendar/index.html

This might be a nice example for you to inspect as well. The index.html includes the full ext-all framework. (they also have some magic, in using various themes, please see shared/include-ext.js)
Index.html has also also it's own header. The trick here, will be to use contentEl, to extract that HTML part and insert it into an Ext JS Component, so it can be part of the Sencha (border) layout.
(contentEl, should point to an html id).
Open src/App.js, and notice how they create a new viewport in the constructor. Note: By using the contentEl, the header will be overridden with Sencha styles. You will need to tweak the styling probably.

I hope these ideas can help you further!

Can I combine Sencha Touch or Ext JS with Angular JS?

Posted on in Ext JS 5 & 6 Ext JS 6 Questions

The Sencha frameworks are web technologies, in theory it would be possible to wire up any external library you like. That said, what are you trying to do?

Ext JS is very complete (all in one) frameworks. It can do everything that Angular JS / Angular 2 can do and much more. For example; Angular is great for defining an architecture; in Ext JS we provide MVC and or MVVM with a very great data package (for retrieving external data), and our own Sencha class system, for extending and reusing components.

When using Angular, you probably will need to include jQuery for DOM modification, jQuery plugins, an UI & theming solution (like Twitter bootstrap) for components and themes.
You will need to maintain all these packages, which all work for different browser versions, and they all needs to be configured in a different way.

An advantage of Sencha, is that our products are: "one-stop-shops". We provide all of the above in one framework (SDK), and we don't work with HTML but with components. That’s great for maintainability and re-usability, because everything works consistent. It's a commercial product, you won't need to worry that your Sencha app will break in the next 5 or 10 years.

Back to my first question; it might be possible that what you are trying to achieve doesn’t need Angular JS at all.

Edit: Do you mean the other way around? Can you integrate Ext JS within Angular 2? Sencha is currently working on an Angular 2 bridge. So you can embed your Ext JS 6 advanced components within Angular.