【问题标题】:Angular 8 Typescript How to set value of export const from another component?Angular 8 Typescript 如何从另一个组件设置导出常量的值?
【发布时间】:2020-05-29 04:26:45
【问题描述】:

我想从另一个组件更改名为 bdg_m_1 的变量的值。我可以从同一个打字稿文件中更改 bdg_m_1 的值。这是我的代码。

文件名: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, 
     }
  }, 
];

【问题讨论】:

    标签: angular


    【解决方案1】:

    您可以在 nav.ts 中键入以下代码

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

    当你想包含配置对象时,

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

    【讨论】:

      【解决方案2】:

      您只需将其导出,然后将其导入您要更改的组件中。

      声明:

      export let bdg_m_1:string = "10" ;
      

      其他组件:

      import bdg_m_1 from 'nav.ts';
      
      bdg_m_1 = '11';
      

      编辑:上面的“解决方案”实际上是错误的。但是,我将其保留在原位,因为它对 Typescript 导入/导出的工作方式有悖常理。

      请参阅this explanation,了解正在发生的事情。

      结果是在导入模块中,big_m_1 实际上是一个绑定,而不是一个变量。所以实际上它是只读的。

      你显然可以做的是:

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

      祝你好运。

      【讨论】:

      • AlanObject,感谢您的帮助...我在 myComponent 中收到以下错误,我还声明了 export let bdg_m_1:string = "10" ;在 nav.ts ...import bdg_m_1 'bdg_m_1' 被声明但它的值永远不会被读取。 ts(6133) 模块 '"d:/angular/_nav"' 没有默认导出。您的意思是改用“d:/angular/_nav”中的“import { bdg_m_1}”吗?ts(2613) 类型“myComponent”上不存在属性“bdg_m_1”。
      • AlanObject,我无法设置该值,但我可以在更改这样的代码后获取该值... import * as a from '../../_nav'; a.bdg_m_1...
      【解决方案3】:

      如果它们与父子相关,您可以通过eventEmitter 发送它。这是an example on stackblitz,如果它不起作用的代码:

      子组件.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:

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

      app.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-child (newNameEmitter)="changeName($event)"></app-child>
      <br>
      name = {{name}}
      

      原则是在你想要的时候发出一个值。你用(newNameEmitter)="changeName($event)"(app.html)在父级中捕获它

      【讨论】:

        【解决方案4】:

        您真正想做的是管理应用程序的(全局)状态。

        选项 1:使用嵌套组件

        如果您有父组件和子组件,只需使用EventEmitters。可能看起来像:

        nav.ts

        export enum MenuName = {
          Menu1 = 'Menu 1',
          Menu2 = 'Menu 2'
        }
        
        export const navItems: INavData[] = [
          {
            name: MenuItem.Menu1,
            ...
          }, 
        ];
        

        child.component.ts

        @Output() badgeChange = new EventEmitter<{menuName: MenuName, value: string}>();
        
        private updateBadge(menuName: MenuName, value: string) {
          this.badgeChange.next({menuName, value});
        }
        

        听听你父母 HTML 中的变化:&lt;app-child (badeChange)="onBadgeChanged($event)"&gt;&lt;/app-child&gt; 和 TS:

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

        选项 2:将服务用于全局状态

        如果你的全局状态很简单,你也可以为你的状态使用服务:

        nav-service.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
            }
          }
        }
        

        在这种情况下,您的菜单组件会监听this.navService.navData$ 的变化,并且更新数据的组件或服务使用this.navService.updateBadge(...) 告诉所有人该值已更改。

        选项 3:使用状态管理库

        如果您的状态比菜单更复杂,我建议使用状态库,例如 NgRxNgXsAkita。按照链接了解更多关于它们的信息,我在我的项目中使用 NgRx。这个想法类似于使用自己的状态服务,除了整个状态保存在一个状态对象中,并且这些库引入了更复杂的概念。

        【讨论】:

          【解决方案5】:

          您不能从任何其他组件更改该变量的值,因为该变量无法从该组件访问。

          你不必做任何大事。您只需导出此变量并将此变量导入其他组件即可。

          Export bdg_m_1:string = '10'
          

          并使用导入变量。

          import bdg_m_1 from nav.ts
          

          并使用其他组件更改值。

          bdg_m_1 = 'abc'
          

          您还可以在导入变量时更改名称,方法是:

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

          【讨论】:

          • 尊敬的 Minal Shah,感谢您的回复...我尝试了您的代码...我能够从 nav.ts 读取值到另一个组件,但我无法设置(更改)值..它在其他组件中向我显示此错误:无法分配给'bdg_m_1',因为它是只读属性.ts(2540)。你能帮忙吗...
          • 我还有一个解决方案。请尝试该解决方案。
          【解决方案6】:

          我对此有另一个建议,你让你的 ts 文件可注入并创建方法来更新你的变量的值,并在你的另一个组件中使用该方法来更新值。 你的服务看起来像这样。

          @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;
              }
             }
          

          并在你的另一个组件中获取此服务的实例,并调用方法 setValue 来更改 bdg_m_1 的值。

          所以在你的组件中添加以下代码:

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

          【讨论】:

          • 亲爱的 Shah,再次感谢您..export const navItems 是 coreUI 模板中预定义的,我们无法修改...根据您的代码,我可以导出一个值从 myComponent 到 nav.ts 成功。导出类之外的导出语句工作正常。我想从 myComponent 的 ngOnInit 传递值。你能给我一个解决方案吗?非常感谢您的帮助...
          • export const bdg_m_1 : string = '10'; // 这个值发送成功 @Component({ templateUrl: "myComponent.component.html", }) export class MyComponentComponent implements OnInit { ngOnInit(): void { bdg_m_1 = 11; //
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-22
          • 2020-01-28
          • 1970-01-01
          • 2015-07-28
          • 2020-07-26
          • 1970-01-01
          相关资源
          最近更新 更多