Introduction

Rico Suter edited this page Sep 8, 2015 · 27 revisions

This introduction explains the framework using an imaginary sample application. The directory structure of the application looks as follows:

  • index.html: The entry page which loads the rest of the application
  • Scripts
    • app.ts: The application entry TypeScript file where the application is initialized.
    • libs: The directory containing the Visto JavaScript Framework, KnockoutJS, JQuery and other libraries.
    • app: The application's default package.
      • views:
        • MainView.html: The HTML code of start view.
        • MainView.ts: The "code-behind" of the start view where the default frame is initialized and the first page is loaded.
    • myPackage: Sample package for this introduction.
      • languages: The directory which contains the JSON files with the translated strings.
      • viewModels: The directory which contains the view models.
        • SamplePageModel.ts (optional): The view model for the view: The view's HTML is bound to this view model using KnockoutJS bindings.
      • views: The directory which contains the views (HTML code and "code-behind" classes)
        • SamplePage.html: The appearance of the view defined as HTML.
        • SamplePage.ts (optional): The "code-behind" class of the view

Framework initialization

The index.html HTML file is the entry page of the VistoJS application. This page loads all required JavaScript and CSS dependencies. One of them is the RequireJS library which automatically executes the code in app.ts. In the app.ts script, the Visto JavaScript Framework is initialized which then renders the specified start view - in our case the MainView view - into the page's body:

import visto = require("libs/visto");

visto.initialize(<visto.IVistoOptions>{
    startView: "MainView",
    supportedLanguages: ["en", "de"]
});

In the MainView the framework is instructed to navigate to the home page. To avoid hiding the loading screen before the page has been loaded, we initialize the frame in the onLoading() method of the start view. The following code shows how to initialize the default frame and navigate to the first page. In our case it is the SamplePage page which is located in the package myPackage:

onLoading() {
    var frame = this.getViewElement("frame"); 
    return visto.initializeDefaultFrame(frame, "myPackage:SamplePage");
}

The following chapters show how the page SamplePage is implemented.

View HTML

First, let's have a look at the HTML declaration of the view SamplePage which can be found in the file myPackage/views/SamplePage.html:

<div>
    <!-- Bindings to view model -->
    <div>
        <label>First name</label>
        <input vs-value="{firstName}" type="text" />
    </div>
    <div>
        <label>Last name</label>
        <input vs-value="{lastName}" type="text" />
    </div>
    <div>
        Full name: {{firstName}} {{lastName}}
    </div>
    
    <!-- Load sub view and pass a constant and an observable parameter -->
    <vs-other-view initial-count="5" label="{lastName}" />
    
    <!-- Define HTML element with ID -->
    <div vs-id="myDiv"></div>
</div>

As you can see in the HTML code, it is possible to bind view model variables to the UI and instantiate other views declaratively using custom tags. The vs-value attribute gets converted into a data-bind attribute with a value key known from KnockoutJS:

data-bind="value: firstName"

Check out view HTML for more information.

View Model

All bindable variables (also known as KnockoutJS observables) are declared and instantiated in the view model. The following code shows the view model class located in the file myPackage/viewModels/SamplePageModel.ts:

import visto = module("libs/Visto");

export class SamplePageModel extends visto.VistoViewModel  {
    firstName = ko.observable<string>();
    lastName = ko.observable<string>();
}

The following code shows the view model class of the OtherView view, to make clear how the passed parameters can be read:

import visto = module("libs/Visto");

export class OtherViewModel extends visto.VistoViewModel  {
    label: KnockoutObservable<string>;

    initialize() {
        // read one-time-to-target parameter
        var initialCount = this.parameters.getNumber("initialCount");
        
        // read one-way-to-target bound parameter
        this.label = this.parameters.getObservableString("label"); 
    }
}

As you can see, the provided parameters can be read using the view's or view model's parameters property. A parameter which must be read only once (one-time) can be read using the method getNumber(), getString(), etc. By calling getObservableXyz() or getObservableArray() it is possible to pass an observable object from the parent view into the sub view and let the sub view react to changes (one-way binding) or write values back (two-way binding).

Check out the page view model and bindings for more information.

View "code-behind"

If needed, it is possible to implement a "code-behind" class for the view. In our sample, a view "code-behind" can be found in the myPackage/views/SamplePage.ts file. All code which directly interacts with the HTML DOM (e.g. JQuery widget creation, etc.) must be placed in this class, because the view model has no access to HTML elements:

import visto = module("libs/Visto");
import ns = module("../viewModels/SamplePageModel");

export class SamplePage extends visto.VistoPage<ns.SamplePageModel>  {
    loaded() {
        // access correctly typed view model 
        var vm = this.viewModel; 
        
        // get child element
        var element = this.getViewElement("myDiv");
    }
}

Check out view for more information.

Paging

The Visto library supports paging and navigation: It is possible to define a DIV element as page frame and navigate forward and backward between pages in this DIV element. It is even possible to implement onNavigatedTo(), onNavigatedFrom() and other event methods on views and view models which are automatically called by the framework.

The following code shows how to navigate to another page in the default navigation frame:

import visto = module("libs/Visto");
import package = module("module");

...

visto.navigate(package, "SecondPage");

Internationalization

The Visto JavaScript Library supports the implementation of multilingual applications. To translate an element you can simply use the vs-translate attribute. The attribute defines a key which is looked up in the language JSON file of the current package. These langauge files can be found in the languages directory of view's package:

<div vs-translate="myTranslatedText"></div>

Because the mechanism internally uses KnockoutJS observables, the language can be changed and the whole user interface is immediately updated. It is also possible to programmatically read language strings.

Check out the internationalization page for more information.