Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call static method of other class in .html (not in .ts)?

Tags:

angular

I created a class ScoreBoard as a global object by calling getInstance():

export class ScoreBoard{
    protected _myNumber : number;
    protected static scoreBoard : ScoreBoard;

    constructor(){
        this._myNumber=3;
    }
    get myNumber():number{
        return this._myNumber;
    }
    set myNumber(_myNumber : number){
        this._myNumber=_myNumber;
    }

    static getInstance() : ScoreBoard{
        if(!this.scoreBoard){
            this.scoreBoard=new ScoreBoard();
        }
        return this.scoreBoard;
    }
}

and trying to call it in a html page:

newscontent.ts

import { Component } from '@angular/core';
import { ScoreBoard } from '../scoreboard';

  @Component({
    templateUrl: 'newscontent.html'
  })
  export class NewsContent {
    constructor() {
  }
}

newscontent.html

<ion-header>
  <ion-navbar>
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title></ion-title>
  </ion-navbar>
</ion-header>
<ion-content fullscreen="true">
    {{ScoreBoard.getInstance().myNumber}}
</ion-content>

but it failed to display as error:

1     689170   error    EXCEPTION: Error in ./NewsContent class NewsContent - inline template:8:31 caused by: undefined is not an object (evaluating 'self.context.ScoreBoard.getInstance')
2     689170   error    ORIGINAL EXCEPTION: undefined is not an object (evaluating 'self.context.ScoreBoard.getInstance')

. . .

how can I call static method of other class in .html?

like image 846
ggrr Avatar asked Nov 10 '16 04:11

ggrr


2 Answers

basically you can't call static methods from the templates (ng2 templates aren't really html but a meta language transformed into html).

Before all, you have to know that the only things that you have access from the component's template are the methods and attributes of an instance of this one and the ng2 components declared into the module. You can't access to the static properties of the component's because you don't have access to the class but only the instance and you cannot access to a class outward of the angular scope because angular doesn't manage it.

Anyway, you have many way to achieve what you want depending what you need.

For example, we can imagine declare a method in the component's class calling your static method.

import { Component } from '@angular/core';
import { OtherClass } from '../otherclass';

@Component({
template: `
    <button (click)="callStaticMethod()">foo</button>
`
})
export class FooBarComponent {


    public callStaticMethod() {
        return OtherClass.staticMethod();
    }
}

Even if this way can be usefull sometimes, in your case, there is no point to do that. If i correctly understood your code, you want an instance of ScoreBoard that could be used in a component's template. To achieve that, angular 2 provides another decorator named Injectable. It adds some metadatas to a class and if you declare it to your NgModule, Angular will provide an instance by the Dependency injection system to each ng2 object requiring the newly created service.

In your case the code could be like the following.

import { Injectable } from '@angular/core';

@Injectable()
export class ScoreBoard{
    protected _myNumber : number;

    constructor(){
        this._myNumber=3;
    }
    get myNumber():number{
        return this._myNumber;
    }
    set myNumber(_myNumber : number){
        this._myNumber=_myNumber;
    }
}



import { Component } from '@angular/core';
import { ScoreBoard } from '../scoreboard';

@Component({
templateUrl: 'newscontent.html'
})
export class NewsContent {
    // the attribute scoreBoard will be filled by angular thanks to the dependency injection
    constructor(public scoreBoard:ScoreBoard) {}

    ngOnInit() {
        // You can now use your service in the component's body
        this.scoreBoard.myNumber = 18;
    }
}


<ion-header>
    <ion-navbar>
        <button ion-button menuToggle>
            <ion-icon name="menu"></ion-icon>
        </button>
        <ion-title></ion-title>
    </ion-navbar>
</ion-header>
<ion-content fullscreen="true">
    <!-- or you can use it directly from the template via the NewContent's attribute *scoreBoard*-->
    {{scoreBoard.myNumber}}
</ion-content>

With this method, you will have access to your service anywhere you need it, you just have to inject it. However be careful, Angular provides the same instance of a service for each ng2 object requiring it except if you ask it intentionnally. I recommand you to take a look of the documentation for more information about the dependency injection system.

like image 106
Polochon Avatar answered Nov 06 '22 16:11

Polochon


import { Component } from '@angular/core';
import { ScoreBoard } from '../scoreboard';

  @Component({
    templateUrl: 'newscontent.html'
  })
  export class NewsContent {

  scoreboardInstance = ScoreBoard.getInstance();

  constructor() {
  }
}

<ion-header>
  <ion-navbar>
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title></ion-title>
  </ion-navbar>
</ion-header>
<ion-content fullscreen="true">
    {{scoreboardInstance.myNumber}}
</ion-content>
like image 20
Caleb Macdonald Black Avatar answered Nov 06 '22 15:11

Caleb Macdonald Black