глобальная функция в Ionic 2/Angular 2

Как настроить глобальную функцию, к которой можно получить доступ во всех представлениях?

В app.component.ts я добавил простой метод

  openShare() {console.log("button clicked")} 

а потом в моей навигации у меня есть

  <button ion-button right (click)="openShare()">
  <ion-icon name="md-share"></ion-icon>
</button>

Когда я пытаюсь получить доступ к этому с любой страницы, я получаю следующее.

self.context.openShare is not a function

Однако он выполняется нормально, если я помещаю его непосредственно в конструктор (например, this.openShare(); ), но при вызове с любой страницы с помощью функции (щелчка) он просто не работает.

Является ли app.component.ts глобальным? Я думал, что это место, где я мог бы разместить его, но, возможно, я что-то упустил.

В основном это функция для простой кнопки на навигации, мне нужно, чтобы она была глобальной, поскольку она используется на каждой странице.

Любая помощь будет оценена, все еще выясняя Ionic 2.


person limit    schedule 02.04.2017    source источник
comment
Попробуйте пользовательскую директиву.   -  person Harish Kommuri    schedule 02.04.2017
comment
Любой пример кода, как бы я это сделал?   -  person limit    schedule 02.04.2017
comment
angular.io/docs/ts/latest/guide/attribute-directives. html   -  person Harish Kommuri    schedule 02.04.2017
comment
@HarishKommuri - это тоже может сработать. Если у кого-то есть простой пример, буду признателен. Я более нагляден, не прошу писать код, просто пример метода щелчка.   -  person limit    schedule 02.04.2017


Ответы (3)


Вы можете использовать Directive.

Попробуйте следующим образом.

Поместите следующий код в отдельный файл директив. (социальный обмен.directive.ts);

import { Directive, HostListener } from '@angular/core';

@Directive({
  selector: '[socialSharing]'
})
export class SocialSharing {

  constructor() { }

  @HostListener('click') onClick() {
    // Your click functionality
  }
}

Импортируйте его в app.module.ts, а затем добавьте в declarations.

В HTML просто добавьте attribute к любому элементу, который является selector в вашем файле директив.

<button ion-button right socialSharing>
 <ion-icon name="md-share"></ion-icon>
</button>

Дополнительная информация:

Передача значений из компонента в директиву.

home.html

  <button ion-button right [socialSharing]="property">
    <ion-icon name="md-share"></ion-icon>
  </button>

home.component.ts

 export class HomePage {

   property: string = 'some url';
    constructor() {}
 }

social-sharing.directive.ts

Импортируйте Input вместе с другими из @angular/core.

import { Directive, Input, HostListener } from '@angular/core';

@Directive({
   selector: '[socialSharing]'
})

export class SocialSharing {
  @Input('socialSharing') str: string;

  constructor() {}

  @HostListener('click') onClick() {
     console.log(this.str);
  }
};

  ngAfterInit() {
     console.log(this.str);
  };
}

Использование элемента в директиве:

social-sharing.directive.ts

Импортируйте ElementRef вместе с другими из @angular/core

 import { Directive, ElementRef, HostListener } from '@angular/core';

 @Directive({
   selector: '[socialSharing]'
 })

 export class SocialSharing {

   // Add ElementRef to constructor

   constructor(el: ElementRef) {};

   ngOnInit() {
      let elRef = this.el.nativeElement;
      console.log(elRef.innerHTML);        
   };
 }
person Harish Kommuri    schedule 02.04.2017
comment
- Эй, спасибо. Это действительно сработало идеально. Много сообщений для людей, желающих знать, как это сделать. Надеюсь, они найдут здесь ваш ответ. Спасибо, очень признателен. - person limit; 02.04.2017

Вы можете легко сделать это с помощью Providers. Когда вам нужно использовать эту функциональность (или провайдера), вам просто нужно inject добавить ее в соответствующий компонент. Вот и все.

Способ 1:

Вы можете создать провайдера с помощью CLI.

> ionic g provider YourProvider

ваш-провайдер.ts

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

    @Injectable()
    export class YourProvider {

      constructor() {
      }

       openShare() {console.log("button clicked")} 
    }

app.module.ts

import { YourProvider } from "../pages/path";

    @NgModule({
      declarations: [
        MyApp,
      ],
      imports: [
        IonicModule.forRoot(MyApp),
       ],
      bootstrap: [IonicApp],
      entryComponents: [
        MyApp,
        ],
      providers: [{ provide: ErrorHandler, useClass: IonicErrorHandler },YourProvider  ]
    })

    export class AppModule { }

ваш-view.ts

       import { YourProvider } from '../../providers/your-provider';

        export class YourViewPage{

          constructor(public yourProvider : YourProvider) {

          }

        openShare(){
           this.yourProvider.openShare(); 
        }

Метод 2. Создайте базовый класс abstract.

мой-базовый-класс.ts

export abstract class MyBaseClass {

  constructor() {
  }

  protected openShare():void {
    console.log("button clicked"); 
  }

}

мой-view.ts

export class MyViewPage extends MyBaseClass {
  constructor()
  {
     super();
  }

       openShare(){
               super.openShare(); 
            }
  }
person Sampath    schedule 02.04.2017
comment
хм.. да, это то, как я сейчас все настроил, но для простой функции кажется слишком много импорта на 20 страницах. Это единственный способ? Это для кнопки в заголовке навигации, которая в основном вызывается на каждой странице. - person limit; 02.04.2017
comment
Спасибо за помощь. Интересно с абстрактным классом, попробую. - person limit; 02.04.2017
comment
уверен. надеюсь, вы поделитесь с нами результатом :) - person Sampath; 02.04.2017

Как уже упоминалось @Sampath, одним из способов было бы использование собственного поставщика. Но поскольку ваш метод очень простой, я думаю, вы можете вместо этого использовать Events. . Это было бы так:

В файле app.component.ts подпишитесь на новое событие:

import { Events } from 'ionic-angular';

constructor(public events: Events, ...) {

  // ...

  events.subscribe('social:share', () => {

    // your code...
    console.log("button clicked");

  });

}

А затем на любой другой странице просто опубликуйте событие, чтобы выполнить эту логику:

function anotherPageMethod() {
  this.events.publish('social:share');
}
person sebaferreras    schedule 02.04.2017
comment
Спасибо, это может сработать. Тем не менее, я не могу поверить в нечто настолько глобальное, как панель навигации, нет простого способа объявить общие методы. Так много для того, чтобы держать его СУХИМ. В Ionic 1 было просто. Что ж, очень признателен за помощь. Спасибо еще раз. - person limit; 02.04.2017