既然Angular是双向数据绑定,为什么要在Angular中使用Redux?

既然Angular是双向数据绑定,为什么要在Angular中使用Redux?,angular,redux,ngrx,Angular,Redux,Ngrx,据我所知,Redux主要用于在javascript应用程序中启用双向数据绑定。这对于不是双向数据绑定的框架非常有用,例如React。但为什么要在已经是本机双向数据绑定的Angular中使用它呢 为了说明我的问题,这里是我在native Angular中使用的代码,该代码用于创建一个存储,以实现两个角度组件之间的变量状态通信: 1)商店 import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' })

据我所知,Redux主要用于在javascript应用程序中启用双向数据绑定。这对于不是双向数据绑定的框架非常有用,例如React。但为什么要在已经是本机双向数据绑定的Angular中使用它呢

为了说明我的问题,这里是我在native Angular中使用的代码,该代码用于创建一个存储,以实现两个角度组件之间的变量状态通信:

1)商店

import { Injectable } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class StoreService {
  customer: any;
  constructor() { }
}
import { Component, OnInit } from '@angular/core';
import { ApiService } from '../api.service'
import { StoreService } from '../store.service'

@Component({
  selector: 'app-mycomponent',
  templateUrl: './mycomponent.component.html',
  styleUrls: ['./mycomponent.component.css']
})
export class MycomponentComponent implements OnInit {

  constructor(
    private api: ApiService,
    private store: StoreService
  ) { }

  ngOnInit() {

    this.api.getData();

  }
}
import { Component, OnInit } from '@angular/core';
import { StoreService } from '../store.service'

@Component({
  selector: 'app-myothercomponent',
  templateUrl: './myothercomponent.component.html',
  styleUrls: ['./myothercomponent.component.css']
})
export class MyothercomponentComponent implements OnInit {   
  constructor(private store: StoreService) { }
}
这个商店是一个原生的Angular服务,我只声明变量customer(是的,键入会更好,但我希望尽可能缩短它)

2)异步api服务

import { Injectable } from '@angular/core';
import { StoreService } from './store.service'

@Injectable({
  providedIn: 'root'
})
export class ApiService {

  constructor( private store: StoreService ) { }

  getData() {
    setTimeout(()=> {
      this.store.customer = {
        name: 'Bob',
        age: 25
      }
    }, 2000);
  }
}
此api服务只有一个异步检索客户数据的方法
getdata()
。我可以使用
http.get
方法,在这种情况下,
setTimeout
中的代码将是可观察订阅的
next()
函数中的代码。 注意,我直接在前一个存储中实例化异步进程的返回

3)使用存储的组件

import { Injectable } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class StoreService {
  customer: any;
  constructor() { }
}
import { Component, OnInit } from '@angular/core';
import { ApiService } from '../api.service'
import { StoreService } from '../store.service'

@Component({
  selector: 'app-mycomponent',
  templateUrl: './mycomponent.component.html',
  styleUrls: ['./mycomponent.component.css']
})
export class MycomponentComponent implements OnInit {

  constructor(
    private api: ApiService,
    private store: StoreService
  ) { }

  ngOnInit() {

    this.api.getData();

  }
}
import { Component, OnInit } from '@angular/core';
import { StoreService } from '../store.service'

@Component({
  selector: 'app-myothercomponent',
  templateUrl: './myothercomponent.component.html',
  styleUrls: ['./myothercomponent.component.css']
})
export class MyothercomponentComponent implements OnInit {   
  constructor(private store: StoreService) { }
}
请注意,除了导入服务存储和api之外,我只使用了一行代码,即调用数据的代码。如果其他组件或任何其他服务已经填充了存储(请参阅下面的第二个组件),则此行将毫无用处

4)组件的HTML模板

<ul>
  <li>Name : {{store.customer?.name}}</li>
  <li>Age : {{store.customer?.age}}</li>
</ul>
<p>
  <input type="text" [(ngModel)]="store.customer && store.customer.name">
</p>
我只导入存储,不需要任何其他代码行

6)前一个组件的HTML模板

<ul>
  <li>Name : {{store.customer?.name}}</li>
  <li>Age : {{store.customer?.age}}</li>
</ul>
<p>
  <input type="text" [(ngModel)]="store.customer && store.customer.name">
</p>

请注意,由于使用了ngModel,所以使用了处理异步的特殊方法。顺便说一下,我想在dorder中导入FormsModule来处理HTML中的输入

现在,在第二个组件中更改客户名称的值,您将在第一个组件中看到其直接和即时的更改

Angular的这种双向数据绑定功能非常强大,而且设置和使用非常简单,我真想知道为什么我应该使用Redux或NgRx。你能解释一下我为什么要这么做吗


感谢您的帮助。

实现同样的目标肯定有很多方法,Redux正在尝试解决这些问题。 Redux实际上并不适用于双向数据绑定。开发它是为了维护整个应用程序的状态

page可能是了解Redux原因的正确位置

在我看来,使用Redux/Ngrx有以下优点

  • 代码更易于维护
  • 可预测的代码(很容易调试,提供了Redux的devtools)
  • 状态是不可变的,并且仅从一个位置(还原器)更新
据我所知,Redux主要用于在javascript应用程序中启用双向数据绑定。这对于不是双向数据绑定的框架非常有用,例如React。但为什么要在已经是本机双向数据绑定的Angular中使用它呢

这句话是错误的,所以它之后的一切都是基于对Redux解决的问题的错误印象

它与数据绑定无关,但您已经接近它解决的问题了

Redux解决了
让x={y:2}的问题;x、 y=3
隐藏一个值的变异,JavaScript应用程序中的所有其他内容都很难知道
x.y
何时更改

历史上,像AngularJS 1.x这样的框架使用观察者,将模板表达式与其以前的值进行比较,以查看其是否已更改,但如果模板引用的是
x
,并且内部值
x.y
已更改,则观察者不会看到它

React只有单向数据绑定,但is也有同样的副作用。如果将
x
作为属性传递给
,则如果
x.y
发生更改,组件将不会呈现更新

Angular也有这个问题

程序员通过克隆对象来解决这个问题,这样数据绑定就会看到变化,并将变化呈现给DOM

比如,

设x={y:1};
设next={…x,y:2};
console.log(x==next);//打印错误
上面的代码不是直接变异
x.y=2
而是用新值创建一个新对象,并且
x
next
值之间的比较会产生
false
,它告诉大多数框架(如Angular或React)数据已经更改,需要它的任何内容都应该更新

那么这和Redux有什么关系呢

Redux是一个缩减器框架。它基于这样一种思想,即它使用reducer函数来执行上述工作。
{…x,y:2}
的变异非常简单,但Redux为开发人员提供了工具,使其能够以更易于管理的方式完成。例如,选择器和操作是抽象产生新的变异值的工作的方式


如果JavaScript可以看到
x!==x
x.y
发生变化时,我们就不需要重复了。

很难用一个小项目来说明通量模式的优势,其复杂性与“你好,世界!”。就像一个简单的场景“获取一个JSON并将其放在屏幕上”一样,很难论证RxJS的优点——不仅承诺是完全足够的,而且即使是好的旧回调也可以做到这一点

国家管理也是如此。我最近开始将我的项目从“隐藏在多个服务和组件中的杂乱无章的分布式状态”架构迁移到NGX。例如,组件只需一行
@Select(RelevantStore.relevantProperty)
,而无需咨询路由器状态和一系列服务,这一事实大大提高了代码库的可维护性