angular小白,想实现一个效果,多次尝试后无果,请求帮助,谢谢

父组件有一个对象,就叫对象A,对象里面的数据用于渲染父组件视图,子组件有一个对象B,用于渲染子组件视图。
要实现的效果就是:在子组件界面上编辑对象B的数据(就像修改个人信息一样),再在子组件.ts中监听对象B里面的每一个数据的变化,只要有任何一个数据变化,就需要去改变父组件对象A里面数据,再通过对象A改变父组件视图。

自己做过的尝试:
1.用doCheck监听,能实时监听到数据的变化,再用事件触发机制去触发通知父组件改变对象A的值,再修改视图。(或者将对象A传入子元素,通过监听到对象B数据改变后,直接在子组件里面直接修改对象A的数据),两种方式的效果一致,可以改变,问题是会触发angular的检测机制,angular检测机制会检测到父组件两次渲染视图数据不同而报错。处理方法:1.屏蔽检测机制:能屏蔽console报错,但是机制依旧存在,达不到效果。2.改变emit的触发方式,将触发方式改为异步触发,能达到预期的想过,但是emit会一直触发,就像interval一样,会造成更严重的问题。
2。用naOnChange监听,将对象B先在父元素里面获取,在传入子元素,通过ngOnChang来监听对象B的变化,从而改变对象A,问题:ngOnChange无法监听到对象里面的数据变化,只能监听基本数据类型的数据变化。后面改变值的时候可能也会触发检测机制

angular小白一个,没有参透angular,实在想不到其他的实现办法,请求大家的帮助

阅读 3.1k
2 个回答

其实我很不喜欢父子组件的说法,我个人觉得这里不存在父子的关系,因为真实的 DOM 最后指不定谁包含谁,组件和组件之间只有谁被谁使用的关系。

那么问题就是,有一个组件内部维护了一个对象 B,其 view 会有控件对 B 的属性进行编辑,编辑后需要通知外部数据有改动,另一个组件会使用这个组件并监听数据改动。

那么问题就来了,这个组件的内部对象什么时候会被改动??为什么会需要监听 doCheck/ngOnChange ? 这俩货是用来处理组件的输入数据有变动的呀。你这个自己的数据的改动必然来自 View 中的用户输入,用户输入就会有事件,你要做的是在这些事件产生时,你再额外以组件事件的形式对外通知一下,我的数据有变动,使用者请知悉。你如果使用的是 FormGroup 那更简单直接 valueChange 做一下 map 就是你要的事件。

建议为每个子组件建立一个eventEmit,在组件中手动的处理变更。如果组件有变更,则使用eventEmit来弹出数据。然后在父组件中接收弹出值,进而完成小红点的显示与隐藏。

由于angular中提供了formGroup,所以即使子组件中有多个变更项(formControl),我们也可以轻易地获取到数据是否发生了变更。

formGroup.valueChanges.subscribe(() => {  
  // 当formGroup中的任意项发生变更时,均会触发本方法  
  this.eventEmit.emit();
});

如果你当前组件的变化项的类型,并不是适用于formGroup的formControl,则需要将其改造为formControl(这也是正统的做法),具体的方法可参考此文章此文章

希望能帮到你。

下面在瞎说几句为什么不能够使用doCheck或是ngOnChange来完成上述功能,由于部分的理论并没有深入的验证,所以必然有不对的地儿,我瞎说你就瞎听吧。


其实angular中移除了在angularjs中的数据监听功能的,所以原则上是没有办法做到监听某个数据的变化从而实现某些功能的。在angular中使用了观察者模式来代替了效率低下的数据监听,这样做的好处是大幅提高了angular的执行效率(同样是渲染一个1000条数据的表格,使用观察者模式的angular的效率要明显高于以前使用了数据监听的angularjs)。

但angular的确可以获取数据的变化,进而在数据变化时重新进行V层的渲染。但这并不是数据监听而是基于zone.js的变更检测,具体的内容可以查看下李宜衡关于angular的变化检测一文

doCheck这个方法本质上与变更检测并没有半点关系,该函数将在angular认为用户可能对组件产生变更影响时被调用(鼠标事件、键盘事件等)。更主要的,我们似乎也没有比较高效的方法来检测某个对象是否发生了深度变化(除非自己写一个deep compare方法 ---- 这与angular的变更检测机制背到而驰),所以在doCheck方法中实现变更检测并不合适。

ngOnChange方法在angular检测到数据变更时被自动调用。但angular的变更检测并不是deep检测。angular判断某个对象是否变更的标准是:1. 比较该值或该对象的引用 2. 比如某对象的属性值或某对象的属性的引用值。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏