为什么我应该在Angular中使用Redux,因为Angular是双向数据绑定? [英] Why should I use Redux in Angular as far as Angular is two-way data binding?

查看:60
本文介绍了为什么我应该在Angular中使用Redux,因为Angular是双向数据绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 ?

为了说明我的问题,这里是我在本机Angular中使用的代码来创建一个存储,该存储允许在两个Angular组件之间进行变量状态的通信:

To illustrate my question here is the code that I use in native Angular to make a store that enables the communication of a variable state between two Angular components :

1)商店

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

这家商店是本机Angular服务,我只声明变量客户(是的输入会更好,但我想尽可能地缩短它).

This store is a native Angular service where I only declare the variable customer (yes typing would be better but i want to shorten it as much as possible).

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()函数中的代码. 请注意,我直接在以前的商店中实例化了异步过程的返回.

This api service has only one method getdata() that retrieves the customer data asynchronously. I could use an http.get method and in this case the code inside the setTimeout would be the code in the next() function of the observable subscribe. Note that I instanciate the return of the async process directly in the former store.

3)使用商店的组件

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之外,我仅使用一行代码,该代码需要数据.如果其他组件或任何其他服务已经填充了商店,则此行将无用(请参见下面的第二个组件)

Note that except importing the services store and api, I use only one line of code, the one that call for data. This line would be useless if an other component, or any other service, would have already populated the store (see the second component below)

4)组件的HTML模板

<ul>
  <li>Name : {{store.customer?.name}}</li>
  <li>Age : {{store.customer?.age}}</li>
</ul>

请注意,我直接在模板中使用商店,以确保与也导入同一商店的其他组件进行双向数据绑定. 请注意使用管理异步变量store.customer的elvis运算符?..

Note that I use directly the store in the template to ensure the two-way data binding with the other components that also imports the same store. Note the use of the elvis operator ?. that manages the async variable 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) { }
}

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

I only import the store, I have no need for any other line of code.

6)前一个组件的HTML模板

<p>
  <input type="text" [(ngModel)]="store.customer && store.customer.name">
</p>

请注意由于使用ngModel而导致的处理异步的特殊方法.顺便说一句,以dorder导入FormsModule来处理HTML中的输入.

Note the special way to handle the asynchronism because of the use of ngModel. By the way think to import the FormsModule in dorder to handle the input in the HTML.

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

Now change the value of the customer name in the second component and you will see its direct and instantaneous change in the first component.

Angular的这种双向数据绑定功能如此强大,并且设置和使用起来如此简单,我真的很奇怪为什么我宁愿使用Redux或NgRx.你能解释一下我为什么要这么做吗?

This two-way data binding of Angular is so powerfull, and so simple to setup and use, that I really wonder why I should rather use Redux, or NgRx. Could you please explain me why I should ?

感谢您的帮助.

推荐答案

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

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解决的问题的不正确印象.

That statement is wrong, and so everything else after it is based upon an incorrect impression of what problem Redux solves.

它与数据绑定无关,但是您很接近它解决的问题.

It has nothing to do with data binding, but you're close to the problem it solves.

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

Redux solves the problem that let x = {y: 2}; x.y = 3; hides a mutation of a value, and everything else in your JavaScript application will have a difficult time knowing when x.y changes.

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

Historically, frameworks like AngularJS 1.x used watchers that would compare a template expression with its previous value to see if it has changed, but if you're template is referencing x and the inner value x.y has changed, then the watcher doesn't see it.

React仅具有单向数据绑定,但由于相同的副作用而受到困扰.如果将x作为属性传递给<MyComponent x={x}/>,则如果x.y更改,组件将不会呈现更新.

React has only one-way data bindings, but is suffers from the same side effect. If you pass x as a property to <MyComponent x={x}/> the component will not render an update if x.y changes.

Angular也遭受这个问题.

Angular suffers from this problem as well.

程序员通过克隆对象解决此问题,以便数据绑定将突变视为正在更改,并将更改呈现给DOM.

Programmers solve this problem by cloning objects so that the data bindings would see the mutation as changing, and render the changes to the DOM.

例如;

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

上面的代码不是直接使x.y = 2突变,而是使用新值创建了一个新对象,并且xnext值之间的比较产生了false,该值告诉大多数框架(如Angular或React),数据已经更改,需要更新的任何内容.

Instead of directly mutating x.y = 2 the above code creates a new object with the new value, and the comparison between x and the next value yields false which tells most frameworks like Angular or React that the data has changed, and anything that needs it should be updated.

那与Redux有什么关系?

So what does this have to do with Redux?

Redux是一个 reducer 框架.它基于这样的想法,即它使用化简函数来执行上述工作. {...x, y:2}的突变确实很简单,但是Redux为开发人员提供了工具,使其可以更轻松地进行管理.例如,选择器和操作是抽象化产生新突变值的作品的方法.

Redux is a reducer framework. It's based upon the idea that it uses reducer functions to perform the above work. The mutation of {...x, y:2} is really simple, but Redux provides tools for the developer to do that in easier to manage ways. For example, selectors and actions are ways of abstracting the work that produces a new mutated value.

如果更改x.y时JavaScript可以看到x !== x,那么我们就不需要Redux.

If JavaScript could see that x !== x when x.y is changed, then we wouldn't need Redux.

这篇关于为什么我应该在Angular中使用Redux,因为Angular是双向数据绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆