Class 角度2:用于所有组件的功能

Class 角度2:用于所有组件的功能,class,inheritance,angular,typescript,angular2-components,Class,Inheritance,Angular,Typescript,Angular2 Components,我有一个angular 2网页包项目,目前我有一些功能在几个组件中重复。我希望从一个“主”类或组件继承所有这些组件(无论哪一个有效),以便能够从所有需要它们的组件调用函数 例如,如果我在3个不同的组件中有一个函数foo: foo(s: string){ console.log(s); } class parent{ foo(s: string){ console.log(s); } } 我希望您将此函数移动到另一个文件/类/组件: foo(s: string){ co

我有一个angular 2网页包项目,目前我有一些功能在几个组件中重复。我希望从一个“主”类或组件继承所有这些组件(无论哪一个有效),以便能够从所有需要它们的组件调用函数

例如,如果我在3个不同的组件中有一个函数foo:

foo(s: string){
  console.log(s);
}
class parent{
  foo(s: string){
    console.log(s);
  }
}
我希望您将此函数移动到另一个文件/类/组件:

foo(s: string){
  console.log(s);
}
class parent{
  foo(s: string){
    console.log(s);
  }
}
并且有办法从给定的组件调用我的foo函数。例如:

class child{
  constructor(){
    foo("Hello");
  }
}

我将如何使用Angular 2/Typescript实现这一点?

我将使用一项服务,下面是我的一个应用程序的一个简短示例:

import {Injectable} from '@angular/core';
import * as _ from 'lodash';

@Injectable({
  providedIn: 'root' // Just do @Injectable() if you're not on Angular v6+
})

export class UtilsService {

  findObjectIndex(list: any[], obj: any, key: string): number {

    return _.findIndex(list, function(item) {
      return obj[key] === item[key];
    });
  }

  findObjectByQuery(list: any[], key: string, query: string): any {

    return _.find(list, function(item) {
      return item[key].toLowerCase() === query.toLowerCase();
    });
  }
}
然后你可以把这个服务注入任何东西,这是非常有用的,你可以保持干爽

您只需像这样注入它:

import {UtilsService} from 'app/shared';

export MyComponent {

  constructor(private utils: UtilsService) {
    utils.findObjectIndex([], {}, 'id'); // just an example usage
  }
}
编辑:

正如@aalielfeky的回答所说,您可以使用静态函数

但是,我个人会避免使用静态函数,因为它们几乎不可能进行正确的测试,而且一旦需要在其中一个函数中使用的构造函数中注入某些内容,就会给您带来麻烦。因为静态函数不能使用注入的任何东西

不要犯和我一样的错误,因为你将不得不重写很多代码

编辑2: 您还可以使用另一种方法,即仅使用普通函数。如果您的函数不需要依赖项注入,这可能是一个好主意,这通常是简单帮助器函数的情况。只需创建一个文件,比如说
helpers.ts
(如果您有许多函数,则每个函数创建一个文件),然后执行以下操作:

或其他语法:

export sum(a: number, b: number) => {
  return a + b;
}
现在,您可以使用以下任一导入语句(取决于您是将所有函数都放在一个文件中,还是每个函数有一个文件):


这种方法的一个优点是,它很容易进行树摇动,而且与使用服务相比,单元测试也稍微容易一些,因为您不需要向测试中添加额外的代码来让服务工作。

如果您想使用继承,它是
扩展
关键字:

父类.class.ts

class parent{
  foo(s: string){
    console.log(s);
  }
}
import { Component } from "@angular/core";
import { parent } from "./parent.class";

@Component({
  selector: 'child',
  template: `<div>{{myMessage}}</div>`
})
export class child extends parent {
  myMessage: string = "Hello";

  constructor(){
    super.foo(this.myMessage);
  }
}
子组件.ts

class parent{
  foo(s: string){
    console.log(s);
  }
}
import { Component } from "@angular/core";
import { parent } from "./parent.class";

@Component({
  selector: 'child',
  template: `<div>{{myMessage}}</div>`
})
export class child extends parent {
  myMessage: string = "Hello";

  constructor(){
    super.foo(this.myMessage);
  }
}
从“@angular/core”导入{Component};
从“/parent.class”导入{parent};
@组成部分({
选择器:'子',
模板:`{myMessage}}`
})
导出类子级扩展父级{
myMessage:string=“Hello”;
构造函数(){
super.foo(this.myMessage);
}
}

请注意,任何装饰信息都将丢失,因此不要将其应用于基类,并期望子类将拥有它


为了这些目的而使用继承就差不多了。共享服务甚至静态类的其他方法也是可行的。这实际上取决于您试图用它们实现什么,以及什么模式最适合您的用例。

您可以创建所有方法都是静态的类

export class Utils {
    public static log(msg:string){
        console.log(msg);
    }
}
然后,只需将其导入您想要使用的位置

import {Utils} from './utils'

class parent{
   foo(s: string){
     Utils.log(s);
   }
}

class child{
   constructor(){
      Utils.log("Hello");
   }
}

您可以创建包含所有常用函数的
utils.ts

export default class Utils {
    static doSomething(val: string) { return val; }
    static doSomethingElse(val: string) { return val; }
}
然后你可以使用下面的方法

import Utils from './utils'

export class MyClass {
     constructor()
     {
         Utils.doSomething("test");
     }
}

您可以使用继承从您的超类调用这些函数,也可以使用静态函数创建一个类,从任何您想要的地方调用它们。哪一个适合你?你能给我解释一下如何使用其中一个,或者把我和解释它的资料联系起来吗?例如,我很难理解我应该把另一个文件放在哪里,我可以“导入”并从中继承。不知何故,我忘记了依赖注入。正如@Chrillewoodz所建议的,依赖注入不起作用吗?我们是否需要在utils方法前面添加
private
关键字?@pro。这意味着这样做将导致函数在服务之外不可用。因此,无论如何,我们不能在服务之外使用该功能。始终需要在构造函数中添加
私有别名:serviceName
,我们将在其中使用它。@pro.means这是因为它是一个可注入的,您可以按照您所说的进行注入。即使在注入服务后,向函数添加private也不会使其可用。感谢您的解释。如果我写了
public alias:serviceName
,它仍然可以工作(有时对于某些服务),我不知道原因是什么?