angular - 既然 Angular 是双向数据绑定(bind),为什么我应该在 Angular 中使用 Redux?

标签 angular redux ngrx

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

为了说明我的问题,我在 native Angular 中使用的代码创建了一个能够在两个 Angular 组件之间进行变量状态通信的商店:

1) 店铺

import { Injectable } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class StoreService {
  customer: any;
  constructor() { }
}

这家商店是一个原生 Angular 服务,我只声明变量 customer(是的,打字会更好,但我想尽可能缩短它)。

2) 异步api服务 e
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) 一个使用 store 的组件
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();

  }
}

请注意,除了导入服务商店和 api 之外,我只使用了一行代码,即调用数据的那一行。如果其他组件或任何其他服务已经填充了商店,则此行将无用(请参阅下面的第二个组件)

4) 组件的HTML模板
<ul>
  <li>Name : {{store.customer?.name}}</li>
  <li>Age : {{store.customer?.age}}</li>
</ul>

请注意,我直接使用模板中的 store 来确保与同样导入同一 store 的其他组件的双向数据绑定(bind)。
注意使用 elvis 运算符 ?.管理异步变量 store.customer .

5) 另一个组件,它修改了商店
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) { }
}

我只导入商店,不需要任何其他代码行。

6) 前一个组件的HTML模板
<p>
  <input type="text" [(ngModel)]="store.customer && store.customer.name">
</p>

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

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

Angular 的这种双向数据绑定(bind)是如此强大,而且设置和使用如此简单,我真的想知道为什么我宁愿使用 Redux 或 NgRx。你能解释一下我为什么要这么做吗?

感谢帮助。

最佳答案

As far as I understand Redux is mainly intended to enable the two-way data binding in a javascript app. This is very usefull for frameworks that are not two-way data binding, as React for instance. But why using it in Angular that is already natively two-way data binding?



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

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

Redux 解决了 let x = {y: 2}; x.y = 3; 的问题隐藏一个值的突变,你的 JavaScript 应用程序中的其他所有内容将很难知道何时 x.y变化。

从历史上看,像 AngularJS 1.x 这样的框架使用观察者来比较模板表达式和它之前的值,看看它是否已经改变,但是如果你的模板引用了 x和内部值x.y已经改变了,然后观察者看不到它。

React 只有单向数据绑定(bind),但也有同样的副作用。如果您通过 x作为 <MyComponent x={x}/> 的属性(property)如果 x.y,组件将不会呈现更新变化。

Angular 也遇到了这个问题。

程序员通过克隆对象来解决这个问题,以便数据绑定(bind)将更改视为更改,并将更改呈现给 DOM。

例如;

let x = {y:1};
let next = {...x, y:2};
console.log(x === next); // prints false

而不是直接变异 x.y = 2上面的代码用新值创建了一个新对象,x 之间的比较和 next值(value) yield false它告诉大多数框架,如 Angular 或 React,数据已更改,任何需要它的东西都应该更新。

那么这和 Redux 有什么关系呢?

Redux 是 reducer 框架。它基于使用 reducer 函数来执行上述工作的想法。 {...x, y:2} 的突变确实很简单,但是 Redux 为开发人员提供了工具,以更易于管理的方式做到这一点。例如,选择器和操作是抽象产生新变异值的工作的方式。

如果 JavaScript 可以看到 x !== xx.y改变了,那么我们就不需要 Redux。

关于angular - 既然 Angular 是双向数据绑定(bind),为什么我应该在 Angular 中使用 Redux?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59287964/

相关文章:

typescript - Angular 2 下载文件 : corrupt result

javascript - 如何使用 angular2-moment 显示 1 分钟前的时间

angular - NgRx:监听服务中的状态变化而不是使用 Effect

angular - 如何保持 RxJ 干燥

javascript - Angular:未创建 Cookie

angular - NullInjectorError : No provider for MediaMatcher

javascript - 如何通过react-redux connect使用React.memo?

javascript - React Redux - 在输入字段中显示以 Redux 状态存储的字符串

javascript - 当另一个 Action 被触发时,处于 redux 状态的对象消失

angular - redux 和 ngrx - 避免通过同一 reducer 中的更改触发不必要的值