据我了解,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 !== x
当x.y
改变了,那么我们就不需要 Redux。
关于angular - 既然 Angular 是双向数据绑定(bind),为什么我应该在 Angular 中使用 Redux?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59287964/