ตัวแปรสากลเชิงมุม 4/5/6


116

ฉันต่อสู้กับการสร้างตัวแปรส่วนกลางในแอปพลิเคชัน Angular 2 ของฉัน

ฉัน googled และอ่านโพสต์มากมายบน StackOverflow ในช่วง 3 ชั่วโมงที่ผ่านมาแล้ว แต่ดูเหมือนว่าฉันไม่สามารถทำให้มันใช้งานได้ ฉันหวังว่าคุณจะช่วยฉันได้และฉันขอโทษที่ถามคำถามนี้

ดังนั้นฉันจึงมีไฟล์ชื่อglobals.tsซึ่งมีลักษณะดังนี้:

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


@Injectable()
export class Globals {

  var role = 'test';

}

และฉันต้องการใช้บทบาทตัวแปรในมุมมอง HTML ของส่วนประกอบของฉันดังนี้:

{{ role }} 

ฉันได้เพิ่มไฟล์globals.ts ลงในapp.module.tsแล้วด้วยวิธีต่อไปนี้:

providers: [
  Globals
],

ไม่ว่าฉันจะทำอะไรกับไฟล์นี้มันก็ไม่ได้ผล สิ่งที่ฉันไม่ต้องการทำคือต้องนำเข้าไฟล์ globals.ts ในทุกองค์ประกอบด้วยตนเองซึ่งเป็นสาเหตุที่ฉันต้องการใช้คุณสมบัติผู้ให้บริการ

ฉันหวังว่าคุณจะช่วยฉันได้และขอโทษอีกครั้ง

ขอแสดงความนับถืออย่างสูง,

AE


4
export class Globals { var role = 'test'; }<- นั่นอะไร
zerkms

นั่นควรจะเป็นคลาส Globals ของฉันที่ฉันต้องการเก็บตัวแปรส่วนกลางของฉัน ตัวอย่างเช่นตัวแปร "role" ซึ่งตอนนี้ควรมีสตริง "test" อยู่เพื่อทดสอบว่าตัวแปรส่วนกลางทำงานหรือไม่
AE

มันไม่ใช่ typescript ที่ถูกต้อง
zerkms

ฉันควรลบ "var" หรือไม่
AE

ใช้แล้วได้localStorageอะไร?
suhailvs

คำตอบ:


180

คุณสามารถเข้าถึงGlobalsนิติบุคคลจากจุดของแอปใด ๆ ผ่านทางฉีดพึ่งพาเชิงมุม หากคุณต้องการส่งออกGlobals.roleค่าในแม่แบบของส่วนประกอบคุณควรฉีดGlobalsผ่านตัวสร้างของส่วนประกอบเช่นบริการใด ๆ :

// hello.component.ts
import { Component } from '@angular/core';
import { Globals } from './globals';

@Component({
  selector: 'hello',
  template: 'The global role is {{globals.role}}',
  providers: [ Globals ] // this depends on situation, see below
})

export class HelloComponent {
  constructor(public globals: Globals) {}
}

ฉันระบุGlobalsไว้ในHelloComponentแต่อาจมีให้ในHelloComponent'sองค์ประกอบหลักบางส่วนหรือแม้แต่ในAppModule. มันจะไม่สำคัญจนกว่าคุณGlobalsจะมีเฉพาะข้อมูลคงที่ที่ไม่สามารถเปลี่ยนแปลงได้ (เช่นค่าคงที่เท่านั้น) แต่ถ้ามันไม่เป็นความจริงและสำหรับส่วนประกอบที่แตกต่างกันตัวอย่างเช่น / บริการอาจต้องการที่จะเปลี่ยนที่ข้อมูลนั้นGlobalsจะต้องเป็นเดี่ยว ในกรณีนี้ควรจัดให้อยู่ในระดับบนสุดของลำดับชั้นที่จะใช้ สมมติว่านี่คือAppModule:

import { Globals } from './globals'

@NgModule({
  // ... imports, declarations etc
  providers: [
    // ... other global providers
    Globals // so do not provide it into another components/services if you want it to be a singleton
  ]
})

นอกจากนี้ยังเป็นไปไม่ได้ที่จะใช้varในแบบที่คุณควรจะเป็น

// globals.ts
import { Injectable } from '@angular/core';

@Injectable()
export class Globals {
  role: string = 'test';
}

อัปเดต

ในที่สุดฉันก็สร้างการสาธิตง่ายๆบน stackblitzโดยที่ single Globalsจะถูกแชร์ระหว่าง 3 องค์ประกอบและหนึ่งในนั้นสามารถเปลี่ยนค่าของGlobals.role.


3
แต่เมื่อฉันได้รับมันในองค์ประกอบอื่น (something = globals.role;) ฉันได้รับ 'test' .. ไม่ใช่ค่าที่ฉันกำหนด
punkouter

3
@punkouter ฉันอัปเดตคำตอบด้วยลิงก์สาธิต Plunker หวังว่ามันจะช่วยคุณได้!
60

3
นี่เป็นกระทู้เก่า แต่ฉันแค่อยากจะบอกว่าฉันรักคุณ บันทึกวันของฉัน!
Nie Selam

2
@AtulStha ฉันเพิ่งเปลี่ยนการสาธิตจาก Plunker เป็น Stackblitz ขอบคุณสำหรับปัญหานี้
61

1
@GauravSachdeva คุณสามารถโพสต์ปัญหาของคุณเป็นคำถามแยกต่างหากใน SO ฉันเชื่อว่ามันจะเป็นตัวเลือกที่ดีที่สุด เพิ่มลิงก์ในความคิดเห็นหากคุณต้องการให้ฉันเห็น
61

22

ฉันใช้สภาพแวดล้อมเพื่อสิ่งนั้น มันทำงานโดยอัตโนมัติและคุณไม่ต้องสร้างบริการฉีดใหม่และมีประโยชน์ที่สุดสำหรับฉันไม่จำเป็นต้องนำเข้าผ่านตัวสร้าง

1) สร้างตัวแปรสภาพแวดล้อมในenvironment.tsของคุณ

export const environment = {
    ...
    // runtime variables
    isContentLoading: false,
    isDeployNeeded: false
}

2) นำเข้า environment.tsในไฟล์ * .ts และสร้างตัวแปรสาธารณะ(เช่น "env") เพื่อให้สามารถใช้ในเทมเพลต html

import { environment } from 'environments/environment';

@Component(...)
export class TestComponent {
    ...
    env = environment;
}

3) ใช้ในเทมเพลต ...

<app-spinner *ngIf='env.isContentLoading'></app-spinner>

ใน * .ts ...

env.isContentLoading = false 

(หรือเพียงแค่ environment.isContentLoading ในกรณีที่คุณไม่ต้องการใช้เทมเพลต)


คุณสามารถสร้างชุดลูกโลกของคุณเองได้ภายในสภาพแวดล้อมเช่นนี้:

export const globals = {
    isContentLoading: false,
    isDeployNeeded: false
}

และนำเข้าตัวแปรเหล่านี้โดยตรง (y)


1
แล้วเมื่อคุณสร้างการผลิตล่ะ? คุณมีทุกอย่างในสองที่หรือไม่?
Mulperi

2
นี่เป็นวิธีที่ดีที่สุด @Mulperi ไม่จำเป็นต้องสร้าง globals ใน environment.ts เพียงสร้าง globals.ts ในไดเรกทอรีแอปที่มีการส่งออกด้านบนและนำเข้าไฟล์นี้ที่คุณต้องการใช้ globals เหล่านั้น
PrasadW

1
ฉันเห็นด้วย. ฉันเพิ่งแก้ไขโซลูชันนี้เหมือนกับที่ @PrasadW ชี้ให้เห็น
Martin Slavkovsky

Angular เวอร์ชันใหม่จะใช้แนวทางนั้นตามค่าเริ่มต้นในขณะนี้ มีenvironments/environment.tsและenvironments/environment.prod.tsที่ถูกแทนที่โดยอัตโนมัติ
rugk

0

ไม่แนะนำจริงๆ แต่ไม่มีคำตอบอื่นใดที่เป็นตัวแปรระดับโลกจริงๆ สำหรับตัวแปรระดับโลกอย่างแท้จริงคุณสามารถทำได้

Index.html

<body>
  <app-root></app-root>
  <script>
    myTest = 1;
  </script>
</body>

ส่วนประกอบหรือสิ่งอื่นใดใน Angular

.. ด้านบนขวาหลังการนำเข้า:

declare const myTest: any;

... ภายหลัง:

console.warn(myTest); // outputs '1'

-2

คุณสามารถใช้ออบเจ็กต์ Window และเข้าถึงได้ทุกที่ ตัวอย่าง window.defaultTitle = "ชื่อเรื่องของฉัน"; จากนั้นคุณสามารถเข้าถึง window.defaultTitle โดยไม่ต้องนำเข้าอะไรเลย


นี่คือสิ่งที่ต้องการหลีกเลี่ยง
Scandinave
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.