Starcounter
HomeDownloadDocsCommunity
2.3.1
2.3.1
  • Starcounter Documentation
  • Getting Started
  • Starcounter
    • Collapsing the Stack
      • Complexity and Scalability Tradeoff
      • The Future of Micro-Services
      • 10 Benefits of Collapsing the Stack
    • Integrated Database and Web Server
  • Hello World - Tutorial
    • Create a Database Class
    • Create a Real Time UI
    • First Interactive UI
    • Computed Properties
    • Expense Tracker
    • Cancel and Delete
    • The Next Step
  • Guides
    • Database
      • Database Classes
      • Data manipulation
      • Object Identity and Object References
      • Querying with SQL
      • Data Types
      • Relations
      • Inheritance
      • Sharing data
      • Database Configuration
      • Comparing Database Objects
      • Referential Integrity and Constraints
    • SQL
      • Identifiers
      • Path Expressions
      • Data operators
      • Joins
      • Aggregates
      • Comparisons and Logical Operators
      • Sorting
      • Fetch
      • Offset Key
      • Indexes
      • Literals
      • Query Plan Hints
      • Reserved words
      • Query for Database Classes
      • SQL Isolation Between Applications
    • Transactions
      • Short-Running Transactions
      • Long running transactions
      • Using Transactions
      • Running Background Jobs
      • Commit Hooks
    • Typed JSON
      • JSON-by-example
      • Code-Behind
      • Data Bindings
      • Callback Methods
      • Responding with JSON
      • Accepting JSON in Requests
      • Primitive Arrays and Single Value Types
      • Typed JSON Internals
    • Blendable Web Apps
      • Starcounter MVVM
      • Palindrom
      • Client-Side Stack
      • Sessions
      • HTML Views
      • App Shell
      • Web Components
      • View Attaching
      • View Composing
      • HTML Compositions
      • HTML Views Blending Guidelines
      • Avoiding CSS conflicts
      • Debugging
    • Network
      • HTTP
      • Internal Self Calls
      • Middleware
      • Anonymous or Substitute Handlers
      • URL Aliases and Redirects
      • Network Gateway
      • Static File Server
      • External HTTP Calls
      • WebSocket
      • Avoiding URI conflicts
      • TCP Sockets
      • UDP Sockets
    • Publishing Apps
    • Working with Starcounter
      • Release Channels
      • Starting and Stopping Apps
      • Administrator Web UI
      • Star CLI
      • StarAdmin CLI
      • StarDump CLI
      • Working in Visual Studio
      • Error Log
      • Using HTTPS on NGINX
      • Using HTTPS on IIS
      • Run Starcounter in Production
      • Weaver
      • Investigating App Crashes
      • Configuration Structure
      • Database Refactoring
      • Using Unload/Reload to Modify Database Schema
      • Kernel Questions and Answers
      • Log Files
  • Cookbook
    • Attach an HTTP Request to an Existing Long-Running Transaction
    • Cookie-Based Authentication
    • Timestamp on Object Creation
    • Creating Strongly Typed JSON Collections
    • Migrating From 2.2 to 2.3+
    • Multiple Pages
    • Icons
    • Proposed Project Structure
    • Acceptance Testing with Selenium
    • Requesting a User to Authenticate
    • How to delete unused tables and columns
Powered by GitBook
On this page
  • Introduction
  • Create Code-Behind Files
  • Handling Input Events
  • Referring to Nested Objects
  1. Guides
  2. Typed JSON

Code-Behind

PreviousJSON-by-exampleNextData Bindings

Last updated 7 years ago

Introduction

To create interactivity for the Typed JSON classes, code-behind classes can be added to extend existing Typed JSON. This is done using .json.cs files, which are partial definitions for Typed JSON classes.

Create Code-Behind Files

To create a Typed JSON class with code-behind, choose New item in Visual Studio and then select Starcounter Typed JSON with Code-behind. By creating one of these with the filename "Person", two files will be created:

PersonPage.json
{
}
PersonPage.json.cs
using Starcounter;

namespace MyApp
{
    partial class PersonPage : Json
    {
    }
}

Handling Input Events

Consider this JSON object with a property that is from the client:

PersonPage.json
{
  "FirstName$": ""
}

To observe changes to this property, the code-behind method Handle can be used:

PersonPage.json.cs
partial class PersonPage : Json
{
    void Handle(Input.FirstName action)
    {
        if (action.Value == "Albert")
        {
            Message = "You are not allowed to enter Albert. There can be only one.";
            action.Cancel();
        }
    }
}

The Handle method gets called with a parameter of type Input. Input is the base class for events triggered by the client.

The Input class is auto generated per each JSON view-model. It provides the following properties and methods:

  • property Value - contains the new value of the user input

  • property OldValue - contains the current value of the user input

  • property ValueChanged - boolean, true if the new value is different than the old value

  • method Cancel() - reject the new value. It prevents the propagation of the new value to JSON as well as to the bound data object

  • property Cancelled - boolean, true if the Cancel() method was called

Referring to Nested Objects

JSON-by-example might contain nested objects. For example:

PersonPage.json
{
  "Name": {
     "FirstName$": "",
     "LastName$": ""
  },
  "FullName$": ""
}

Code-behind for the root level and Name-level can be provided as two separate partial classes. For example:

PersonPage.json.cs
partial class PersonPage : Json
{
    void Handle(Input.FullName action)
    {
        var words = action.Value.Split(' ');
        this.Name.FirstName = words[0];
        this.Name.LastName = words[1];
    }

    [PersonPage_json.Name]
    partial class PersonPageName : Json
    {
        void Handle(Input.FirstName action)
        {
            var person = this.Parent as PersonPage;
            person.FullName = action.Value + " " + this.LastName;
        }

        void Handle(Input.LastName action)
        {
            var person = this.Parent as PersonPage;
            person.FullName = this.FirstName + " " + action.Value;
        }
    }
}

The attribute [PersonPage_json.Name] is used to hint what is the path in JSON-by-example that the partial class refers to.

As you might have noticed, accessing a child object from a parent object in code-behind is as simple as providing a path expression: this.Name.FirstName = words[0]. The child property (this.Name) is of known type (PersonPageName).

However, accessing a parent from a child requires casting (var person = this.Parent as PersonPage). This is because there might be various parents that employ this particular child. In general, using the Parent property is discouraged, because it breaks the single-direction data flow. Child should be controlled by the parent and not vice versa.

To get many more examples of how interactivity is handled, take a look at the where the most common UI patterns are demonstrated.

KitchenSink repo
writable