or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

directives.mdindex.mdparameter-management.mdstate-configuration.mdstate-navigation.mdtransition-hooks.mdurl-management.mdview-management.md
tile.json

view-management.mddocs/

View Management

View declaration and component integration for rendering state content with Angular 1.x templates, controllers, and components. Views define how states present content to users through templates, controllers, or Angular 1.5+ components.

Capabilities

Ng1ViewDeclaration

Complete view configuration interface for Angular 1.x view definitions.

/**
 * Angular 1.x view declaration for state content rendering
 */
interface Ng1ViewDeclaration {
  /** HTML template string or function returning template */
  template?: string | Function;
  /** Template URL or function returning URL */
  templateUrl?: string | Function;
  /** Injectable template provider function */
  templateProvider?: IInjectable;
  /** Controller function or registered controller name */
  controller?: IInjectable | string;
  /** Controller alias for scope binding */
  controllerAs?: string;
  /** Injectable controller provider function */
  controllerProvider?: IInjectable;
  /** Angular 1.5+ component name */
  component?: string;
  /** Injectable component provider function */
  componentProvider?: IInjectable;
  /** Component binding mappings from resolve data */
  bindings?: { [key: string]: string };
  /** Scope variable name for resolve data (default: '$resolve') */
  resolveAs?: string;
}

Usage Examples:

// Template-based view
$stateProvider.state('home', {
  url: '/home',
  template: '<div class="home"><h1>{{vm.title}}</h1></div>',
  controller: 'HomeController',
  controllerAs: 'vm'
});

// Template URL view
$stateProvider.state('about', {
  url: '/about',
  templateUrl: 'templates/about.html',
  controller: ['$scope', 'companyInfo', function($scope, companyInfo) {
    $scope.company = companyInfo;
  }],
  resolve: {
    companyInfo: ['CompanyService', function(CompanyService) {
      return CompanyService.getInfo();
    }]
  }
});

// Component-based view
$stateProvider.state('profile', {
  url: '/profile/{userId}',
  component: 'userProfile',
  resolve: {
    userData: ['$stateParams', 'UserService', 
      function($stateParams, UserService) {
        return UserService.getUser($stateParams.userId);
      }]
  },
  bindings: {
    user: 'userData'  // Map resolve 'userData' to component binding 'user'
  }
});

Template Configuration

Various ways to provide templates for view rendering.

Static Templates

/**
 * Static template configurations
 */
interface TemplateConfig {
  /** Inline HTML template string */
  template?: string;
  /** Path to HTML template file */
  templateUrl?: string;
}

Usage Examples:

// Inline template
$stateProvider.state('simple', {
  url: '/simple',
  template: `
    <div class="simple-page">
      <h1>Simple Page</h1>
      <p>This is an inline template.</p>
    </div>
  `
});

// External template file
$stateProvider.state('complex', {
  url: '/complex',
  templateUrl: 'views/complex-page.html'
});

// Template with state parameters
$stateProvider.state('user', {
  url: '/user/{id}',
  templateUrl: function(params) {
    return 'views/user-' + params.id + '.html';
  }
});

Dynamic Templates

/**
 * Dynamic template configurations
 */
interface DynamicTemplateConfig {
  /** Function returning template string */
  template?: (params: RawParams) => string;
  /** Function returning template URL */
  templateUrl?: (params: RawParams) => string;
  /** Injectable template provider function */
  templateProvider?: IInjectable;
}

Usage Examples:

// Dynamic inline template
$stateProvider.state('dynamic', {
  url: '/dynamic/{type}',
  template: function(params) {
    if (params.type === 'admin') {
      return '<admin-dashboard></admin-dashboard>';
    } else {
      return '<user-dashboard></user-dashboard>';
    }
  }
});

// Dynamic template URL
$stateProvider.state('themed', {
  url: '/themed',
  templateUrl: function(params) {
    const theme = params.theme || 'default';
    return `themes/${theme}/main.html`;
  }
});

// Injectable template provider
$stateProvider.state('generated', {
  url: '/generated',
  templateProvider: ['TemplateService', '$stateParams', 
    function(TemplateService, $stateParams) {
      return TemplateService.generateTemplate($stateParams.type);
    }]
});

Controller Configuration

Various ways to provide controllers for view logic.

Static Controllers

/**
 * Static controller configurations
 */
interface ControllerConfig {
  /** Controller function or registered name */
  controller?: IInjectable | string;
  /** Controller alias for scope */
  controllerAs?: string;
}

Usage Examples:

// Registered controller by name
$stateProvider.state('list', {
  url: '/list',
  templateUrl: 'list.html',
  controller: 'UserListController',
  controllerAs: 'vm'
});

// Inline controller function
$stateProvider.state('details', {
  url: '/details',
  template: '<div>{{vm.message}}</div>',
  controller: function() {
    this.message = 'Hello World';
  },
  controllerAs: 'vm'
});

// Injectable controller with dependencies
$stateProvider.state('data', {
  url: '/data',
  templateUrl: 'data.html',
  controller: ['$scope', 'DataService', function($scope, DataService) {
    $scope.data = DataService.getData();
  }]
});

Dynamic Controllers

/**
 * Dynamic controller configuration
 */
interface DynamicControllerConfig {
  /** Injectable controller provider function */
  controllerProvider?: IInjectable;
}

Usage Examples:

// Dynamic controller selection
$stateProvider.state('adaptive', {
  url: '/adaptive/{mode}',
  templateUrl: 'adaptive.html',
  controllerProvider: ['$stateParams', function($stateParams) {
    if ($stateParams.mode === 'advanced') {
      return 'AdvancedController';
    } else {
      return 'BasicController';
    }
  }],
  controllerAs: 'vm'
});

// Dynamic controller with resolve data
$stateProvider.state('personalized', {
  url: '/personalized',
  templateUrl: 'personalized.html',
  resolve: {
    userPrefs: ['UserService', function(UserService) {
      return UserService.getPreferences();
    }]
  },
  controllerProvider: ['userPrefs', function(userPrefs) {
    if (userPrefs.experience === 'expert') {
      return 'ExpertController';
    } else {
      return 'NoviceController';
    }
  }]
});

Component Integration

Angular 1.5+ component integration for modern component-based architecture.

Component Views

/**
 * Component-based view configuration
 */
interface ComponentConfig {
  /** Component name registered with angular.component() */
  component?: string;
  /** Injectable component provider function */
  componentProvider?: IInjectable;
  /** Binding mappings from resolve data to component inputs */
  bindings?: { [key: string]: string };
}

Usage Examples:

// Register component
angular.module('myApp').component('userProfile', {
  template: `
    <div class="user-profile">
      <h2>{{$ctrl.user.name}}</h2>
      <p>{{$ctrl.user.email}}</p>
    </div>
  `,
  bindings: {
    user: '<',
    permissions: '<'
  },
  controller: function() {
    this.$onInit = function() {
      console.log('User profile loaded:', this.user);
    };
  }
});

// Use component in state
$stateProvider.state('profile', {
  url: '/profile/{userId}',
  component: 'userProfile',
  resolve: {
    userData: ['$stateParams', 'UserService', 
      function($stateParams, UserService) {
        return UserService.getUser($stateParams.userId);
      }],
    userPerms: ['userData', 'PermissionService',
      function(userData, PermissionService) {
        return PermissionService.getUserPermissions(userData.id);
      }]
  },
  bindings: {
    user: 'userData',        // Map resolve 'userData' to component 'user' binding
    permissions: 'userPerms' // Map resolve 'userPerms' to component 'permissions' binding
  }
});

Dynamic Components

/**
 * Dynamic component provider for runtime component selection
 */
interface DynamicComponentConfig {
  /** Injectable function returning component name */
  componentProvider?: IInjectable;
}

Usage Examples:

// Dynamic component selection
$stateProvider.state('dashboard', {
  url: '/dashboard',
  resolve: {
    userRole: ['AuthService', function(AuthService) {
      return AuthService.getCurrentUserRole();
    }]
  },
  componentProvider: ['userRole', function(userRole) {
    switch (userRole) {
      case 'admin': return 'adminDashboard';
      case 'manager': return 'managerDashboard';
      default: return 'userDashboard';
    }
  }]
});

Multiple Named Views

Configure multiple views within a single state for complex layouts.

/**
 * Multiple named views configuration
 */
interface MultiViewConfig {
  /** Views object with named view configurations */
  views: { [viewName: string]: string | Ng1ViewDeclaration };
}

Usage Examples:

// Multiple views with different content types
$stateProvider.state('app', {
  url: '/app',
  views: {
    // Header view with component
    'header': {
      component: 'appHeader'
    },
    
    // Sidebar view with template and controller
    'sidebar': {
      templateUrl: 'sidebar.html',
      controller: 'SidebarController',
      controllerAs: 'sidebar'
    },
    
    // Main content area with nested ui-view
    'content': {
      template: '<ui-view></ui-view>'
    },
    
    // Footer with inline template
    'footer': {
      template: '<footer>© 2023 My App</footer>'
    }
  }
});

// Child state targeting specific view
$stateProvider.state('app.dashboard', {
  url: '/dashboard',
  views: {
    'content@app': {  // Target 'content' view in 'app' state
      component: 'dashboardMain'
    }
  }
});

// Shorthand component syntax
$stateProvider.state('layout', {
  url: '/layout',
  views: {
    'header': 'headerComponent',  // Shorthand for { component: 'headerComponent' }
    'content': 'mainContent',
    'sidebar': 'sidebarWidget'
  }
});

Resolve Data Integration

Integration with state resolve data for dependency injection into views.

/**
 * Resolve data integration configuration
 */
interface ResolveIntegration {
  /** Scope variable name for resolve data */
  resolveAs?: string;
  /** Component binding mappings from resolve data */
  bindings?: { [componentBinding: string]: string };
}

Usage Examples:

// Custom resolve scope variable
$stateProvider.state('data', {
  url: '/data',
  template: '<div>Data: {{myData.items.length}} items</div>',
  controller: ['$scope', function($scope) {
    console.log('Resolved data:', $scope.myData);
  }],
  resolve: {
    items: ['DataService', function(DataService) {
      return DataService.getItems();
    }]
  },
  resolveAs: 'myData'  // Resolve data available as $scope.myData
});

// Component bindings from resolve
$stateProvider.state('userEdit', {
  url: '/user/{id}/edit',
  component: 'userEditForm',
  resolve: {
    user: ['$stateParams', 'UserService', 
      function($stateParams, UserService) {
        return UserService.getUser($stateParams.id);
      }],
    roles: ['RoleService', function(RoleService) {
      return RoleService.getAllRoles();
    }]
  },
  bindings: {
    currentUser: 'user',     // Map resolve 'user' to component 'currentUser' binding
    availableRoles: 'roles'  // Map resolve 'roles' to component 'availableRoles' binding
  }
});

Template Factory Integration

Integration with the TemplateFactory service for advanced template handling.

/**
 * Template Factory for advanced template processing
 */
interface TemplateFactory {
  /** Create template from view configuration */
  fromConfig(config: Ng1ViewDeclaration, params: any, context: ResolveContext): Promise<{template?: string; component?: string}>;
  /** Process string template */
  fromString(template: string | Function, params?: RawParams): string | Promise<string>;
  /** Load template from URL */
  fromUrl(url: string | Function, params?: RawParams): Promise<string>;
  /** Process template provider */
  fromProvider(provider: IInjectable, params: RawParams, context: ResolveContext): Promise<string>;
  /** Generate component template */
  makeComponentTemplate(uiView: any, context: ResolveContext, component: string, bindings?: any): string;
}

Error Handling

Common view configuration errors and solutions:

// ERROR: Cannot mix component with template/controller properties
$stateProvider.state('bad', {
  component: 'myComponent',
  template: '<div>Template</div>',  // Error: cannot use with component
  controller: 'MyController'       // Error: cannot use with component
});

// CORRECT: Use component OR template/controller
$stateProvider.state('good1', {
  component: 'myComponent'
});

$stateProvider.state('good2', {
  template: '<div>Template</div>',
  controller: 'MyController'
});

// ERROR: Invalid binding mapping
$stateProvider.state('bad2', {
  component: 'myComponent',
  bindings: {
    user: 'nonExistentResolve'  // Error: resolve 'nonExistentResolve' doesn't exist
  }
});

// CORRECT: Ensure resolve exists for bindings
$stateProvider.state('good3', {
  component: 'myComponent',
  resolve: {
    userData: ['UserService', function(UserService) {
      return UserService.getCurrentUser();
    }]
  },
  bindings: {
    user: 'userData'  // Maps to existing resolve
  }
});