【问题标题】:Angular 2 - What is equivalent to Root Scope?Angular 2 - 什么相当于根范围?
【发布时间】:2016-03-14 10:27:21
【问题描述】:

全部!我有这个组件,当我单击 href 时,如果它是这样的 Angular 1,它应该将变量设置为 Root Scope:

selector: 'my-component'
template : `
            <div (click)="addTag(1, 'abc')">`

constructor() {
    this.addTag = function(id, desc){
        myGlobalVar = { a: id, b: desc};
    };

然后在我的父组件中,页面本身(实际上)我应该这样做:

<my-component></my-component>
<p>My Component is returning me {{ ?????? }}

做这种事情的最佳方法是什么?

【问题讨论】:

  • 将变量添加到根范围是一种不好的做法。取而代之的是蒂埃里的方法。您创建一个 Repository 或 Store 或 Entity 服务来存储您的值。AngularJS 或 Angular2 应该遵循这种方法。

标签: angular


【解决方案1】:

要实现全局变量,您可以实现共享服务。您将能够保存数据,并且所有组件都可以访问它们。

为此,只需实现一个服务并在提升您的应用程序时设置其提供者:

bootstrap(AppComponent, [ MySharedService ]);

注意不要在要使用它的组件的providers 属性中再次定义它。

示例

服务:

export class MySharedService {
  data: any;
  dataChange: Observable<any>;

  constructor() {
    this.dataChange = new Observable((observer:Observer) {
      this.dataChangeObserver = observer;
    });
  }

  setData(data:any) {
    this.data = data;
    this.dataChangeObserver.next(this.data);
  }
}

在组件中使用它:

@Component({
  (...)
})
export class MyComponent {
  constructor(private service:MySharedService) {
  }

  setData() {
    this.service.setData({ attr: 'some value' });
  }
}

如果您想通知组件数据已更新,您可以在共享服务中利用可观察字段:

@Component({
  (...)
})
export class MyComponent {
  constructor(private service:MySharedService) {
    this.service.dataChange.subscribe((data) => {
      this.data = data;
    });
  }
}

查看这个问题了解更多详情:

angular.io 网站上的这个页面也可能让您感兴趣:

【讨论】:

  • 我这样做了:我的组件和父组件导入/提供者/构造器共享服务。我的组件按照您的建议执行 setData 。我的父组件将此作为构造函数:私有_shared:SharedlService。为了显示父组件上的数据,我在导出类语句之后设置了这一行: tst = this._shared.data;在模板上我放置了这个期望看到数据:{{tst | json}} - 但是在调用 setData 后它没有显示结果 :( 你的例子中缺少一些东西?ty,Thierry !
  • 我更新了我的答案,以便为您提供有关在数据更新时收到通知的方式的更多详细信息...随时告诉您这是否解决了您的问题
  • 这对我不起作用。如果我通过一些后端调用设置数据请提供一个 plunker
  • 什么是“dataChangeObserver”函数? @ThierryTemplier
  • 缺失..,dataChangeObserver:任意;
【解决方案2】:

在 Angular2 中,作用域的概念现在等同于组件或指令的成员变量和@Input 属性。当它们引用 DOM 元素时,可绑定属性还包括 DOM 元素本身的那些属性或属性。

在 Angular1 中,您可以在 $rootScope 上定义一个范围变量,并在深度嵌套的子范围内引用它,而无需将其显式传递到指令中,因为范围继承的原型性质。在 Angular2 中,没有范围继承。如果要将数据从父组件的范围传递到直接子范围,则必须通过指令的 @Input 绑定明确地这样做。例如,&lt;directive [myBinding]="model"&gt;&lt;/directive&gt;,父组件范围内的 model 属性正在通过名为 myBinding 的指令的 @Input 属性传递到子指令的范围内。

与 $rootScope 最接近的是@Thierry 的回答:使用共享服务来检索和变异数据,可以通过 DI 将其注入任何组件。与具有全局注入器的 Angular1 不同,Angular2 引入了分层注入器的概念。组件层次链中的每个组件都可以定义自己的注入器。在 Angular2 中,注入器的层次结构参与类型解析的方式类似于在 Angular1 中使用 $scope 继承解析 $scope 变量。

【讨论】:

  • 这里有更好的答案。谢谢
【解决方案3】:

您可以通过使用 angular BehaviorSubjectasObservable 来实现这一点

查看下面的示例代码

服务文件

@Injectable()
export class commonService {
    private data = new BehaviorSubject('');
    currentData = this.data.asObservable()

    constructor() { }

    updateMessage(item: any) {
        this.data.next(item);
    }

}

组件 1

从任意组件设置数据

 constructor(private _data: commonService) { }
 shareData() {
      this.currentValue = this.queryTerm;
      this._data.updateMessage(this.currentValue);
  }

从任何组件监听

constructor(private _data: commonService) { }
ngOnInit() {
        this._data.currentData.subscribe(currentData => this.currentValue = currentData)
    }

您可以使用这种方式在任何组件之间进行通信。

More Info 和其他7 methods

【讨论】:

    猜你喜欢
    • 2018-08-19
    • 2018-01-24
    • 1970-01-01
    • 2019-12-27
    • 2016-10-09
    • 2017-02-08
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    相关资源
    最近更新 更多