简体   繁体   English

Angular 8 Typescript 如何从另一个组件设置导出常量的值?

[英]Angular 8 Typescript How to set value of export const from another component?

I would like to change the value of the variable named bdg_m_1 from an another component.我想从另一个组件更改名为 bdg_m_1 的变量的值。 I am able to change the value of bdg_m_1 from the same typescript file.. Here is my code..我可以从同一个 typescript 文件中更改 bdg_m_1 的值。这是我的代码。

Filename: nav.ts文件名:nav.ts

var bdg_m_1:string = "10" ; // HOW TO CHANGE THIS VALUE FROM ANOTHER COMPONENT

export const navItems: INavData[] = [
  {
    name: "Menu 1",
    url: "/menu_1",
    icon: "icon-speedometer",
     badge: {
       variant: 'info',
       text: bdg_m_1, 
     }
  }, 
];

You just need to export it, then import it in the component that you want to change it.您只需将其导出,然后将其导入要更改的组件中。

Declaration:宣言:

export let bdg_m_1:string = "10" ;

Other component:其他组件:

import bdg_m_1 from 'nav.ts';

bdg_m_1 = '11';

EDIT: The above "solution" is actually wrong.编辑:上面的“解决方案”实际上是错误的。 However I am leaving it in place because it is instructive about something that is counter-intuitive on how Typescript import/export works.但是,我将其保留在原位,因为它对 Typescript 导入/导出的工作方式具有指导意义。

See this explanation for a good explanation of what is going on.有关正在发生的事情的一个很好的解释,请参阅这个解释

The upshot is that in the importing module, the big_m_1 actually is a binding, not a variable.结果是在导入模块中, big_m_1实际上是一个绑定,而不是一个变量。 So in effect it is read-only.所以实际上它是只读的。

What you apparently can do is this:你显然可以做的是:

import thing = require('./nav.ts');
thing.bdg_m_1 = '11';

Good luck.祝你好运。

You could type the following code in nav.ts您可以在 nav.ts 中键入以下代码

let config = {
    bdg_m_1 : "10",
    navItems: [{
        ...
    }]
}
module.exports = config;

And when you want to include config object,当你想包含配置 object 时,

var Config = require('nav.ts');
console.log(Config.bdg_m_1);

You could send it through an eventEmitter if they are parent-child related.如果它们与父子相关,您可以通过eventEmitter发送它。 Here is an example on stackblitz , and the code in case it does not works:这是关于 stackblitz 的示例,以及如果它不起作用的代码:

child-component.ts:子组件.ts:

import { Component, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  nameToSend = '';
  @Output() newNameEmitter = new EventEmitter<string>();

  emitNewName () {
    this.newNameEmitter.emit(this.nameToSend);
  }
}

chil-component.html:冷却组件.html:

<input type="text" [(ngModel)]="nameToSend"/>
<button (click)="emitNewName()">Send new name</button> 

app.ts:应用程序.ts:

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';

  changeName(newName: string){
    this.name = newName;
  }
}

app.html: app.html:

<app-child (newNameEmitter)="changeName($event)"></app-child>
<br>
name = {{name}}

The principle is to emit a value whenever you want.原则是在你想要的时候发出一个值。 you catch it in the parent with (newNameEmitter)="changeName($event)" (app.html)您使用(newNameEmitter)="changeName($event)" (app.html) 在父级中捕获它

What you actually want to do, is to manage your application's (global) state.您真正想要做的是管理您的应用程序的(全局)state。

Option 1 : Using nested components选项 1 :使用嵌套组件

In case you have a parent- and a child-component, just use EventEmitters .如果您有父组件和子组件,只需使用EventEmitters Could look like:可能看起来像:

nav.ts导航.ts

export enum MenuName = {
  Menu1 = 'Menu 1',
  Menu2 = 'Menu 2'
}

export const navItems: INavData[] = [
  {
    name: MenuItem.Menu1,
    ...
  }, 
];

child.component.ts child.component.ts

@Output() badgeChange = new EventEmitter<{menuName: MenuName, value: string}>();

private updateBadge(menuName: MenuName, value: string) {
  this.badgeChange.next({menuName, value});
}

and listen to the change in your parents HTML: <app-child (badeChange)="onBadgeChanged($event)"></app-child> and in TS:并聆听您父母 HTML: <app-child (badeChange)="onBadgeChanged($event)"></app-child>和 TS 中的变化:

onBadgeChanged(change: {menuName: MenuName, value: string}): void {
  // find menu item by `change.menuName`
  // update it's badge value
}

Option 2 : Use a service for global state选项 2 :为全局 state 使用服务

If your global state is simple, you can also use a service for your state:如果您的全局 state 很简单,您还可以为您的 state 使用服务:

nav-service.ts导航服务.ts

export class NavService {
  navData$ = new BehaviourSubject<INavData[]>([
    {
      name: "Menu 1",
      ...
    }, 
  ]);

  updateBadge(menuItemName: string, value: string): void {
    // find menu item by `menuItemName` in `this.navData$.value`
    const menuItem = ...;
    if (menuItem) {
      menuItem.badge.text = value;
      this.navData$.next([...this.navData$.value]); // emit new nav data
    }
  }
}

In this case, your menu-component would listen to changes of this.navService.navData$ and the component or service which updates the data, uses this.navService.updateBadge(...) to tell everyone that the value has changed.在这种情况下,您的菜单组件将监听this.navService.navData$的更改,并且更新数据的组件或服务使用this.navService.updateBadge(...)告诉所有人该值已更改。

Option 3 : Use a state management library选项 3 :使用 state 管理库

If your state is more complex than just a menu, I would suggest to use a state library such as NgRx , NgXs or Akita .如果您的 state 比菜单更复杂,我建议使用 state 库,例如NgRxNgXsAkita Follow the links to learn more about them, I use NgRx for my projects.按照链接了解更多关于它们的信息,我在我的项目中使用 NgRx。 The idea is similar to using an own service for state, except the entire state is kept in one state-object and more sophisticated concepts are introduces by these libraries.这个想法类似于为 state 使用自己的服务,除了整个 state 保存在一个状态对象中,并且这些库引入了更复杂的概念。

You can not change the value of the variable from any other component as this variable is not accessible from that component.您不能从任何其他组件更改变量的值,因为该变量无法从该组件访问。

You dont have to do anything big.你不必做任何大事。 You just have to export this variable and import this variable in the other component.您只需导出此变量并将此变量导入其他组件。

Export bdg_m_1:string = '10'

And import the variable using.并使用导入变量。

import bdg_m_1 from nav.ts

And change the value from the other component using.并使用其他组件更改值。

bdg_m_1 = 'abc'

You can also change the name while importing the variable by using:您还可以使用以下方法在导入变量时更改名称:

import bdg_m_1 as myConst from nav.ts
myConst = 'abc'

I have another suggestion for this, you make your ts file injectable and create method to update the value of your variable and use that method in your another component to update the value.我对此有另一个建议,你让你的 ts 文件可注入并创建方法来更新你的变量的值,并在你的另一个组件中使用该方法来更新值。 your service would look something like this.你的服务看起来像这样。

@Injectable()
export class MyService {

 bdg_m_1 : string = '10';
 navItems: INavData[] = [
     {
        name: "Menu 1",
        url: "/menu_1",
        icon: "icon-speedometer",
        badge: {
          variant: 'info',
          text: bdg_m_1, 
      }
   }, 
   ];
  constructor(){}
  setValue(value: string){
           this.bdg_m_1 = value;
     }
  getNavItems(){
  return this.navItems;
    }
   }

And get instance of this service in your another component and call the method setValue to change the value of bdg_m_1.并在您的另一个组件中获取此服务的实例并调用方法 setValue 来更改 bdg_m_1 的值。

So add following code in your component:因此,在您的组件中添加以下代码:

constructor(private myService: MyService){
   this.myService.setValue('abc');
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM