简体   繁体   English

如何在不订阅每个输入/组件角度变化的情况下更新数据更改的摘要状态?

[英]How to update summary state of data changes without subscribing to every input/component change in angular?

I have a rather complex modal to manage some data state. 我有一个相当复杂的模式来管理某些数据状态。 It has a lot of inputs, selections, checkboxes and other custom components. 它具有很多输入,选择,复选框和其他自定义组件。

Now I would like to show the user some summary hints about what data has been updated during the time modal has been opened and what consequences it would lead. 现在,我想向用户展示一些有关在打开时间模式期间已更新哪些数据以及将导致什么后果的摘要提示。 For example, on some actions, I would like to change the color of the "Update" button, on some actions not to show it at all and for all states show some summary (in a tooltip, for example) of what has been changed. 例如,在某些操作上,我想更改“更新”按钮的颜色,在某些操作上根本不显示它,并且对于所有状态,请显示一些更改的摘要(例如,在工具提示中) 。 Important thing is that it's not just showing that some input fileds were touched and others not, it's again some combination of their state change. 重要的是,这不仅表明某些输入文件已被触摸,而另一些文件未显示,这也是它们状态改变的某种组合。

The problem that I don't use <form> tag at all since most of custom components just don't have name attributes to support it. 我根本不使用<form>标记的问题,因为大多数自定义组件都没有名称属性来支持它。 So I can't write a custom form validator, the main side effect of which will be updating state summary variable (since I need something more complex that just form valid-invalid summary flag). 因此,我无法编写自定义的表单验证器,其主要副作用是更新状态摘要变量(因为我需要的只是表单有效-无效摘要标志,因此需要更复杂的东西)。

I also consider an approach of attaching valueChange or ngModelChange callbacks to all inputs and components to be rather complex in implementation at the current state of development. 我还认为将valueChange或ngModelChange回调附加到所有输入和组件的方法在当前的开发状态下实现起来相当复杂。

So there is a question how can I continuously update state summary variable based on data change. 因此,存在一个问题,如何根据数据更改连续更新状态摘要变量。

I could use setInterval() to update state but its update delay will be something completely arbitrary from the angular update cycle. 我可以使用setInterval()更新状态,但是从角度更新周期来看,它的更新延迟将完全是任意的。

Update state result is used in several places so creating just a function calculating it on request and putting it in all needed places is very ineffective. 更新状态结果在多个位置使用,因此仅创建一个函数即可根据请求对其进行计算并将其放置在所有需要的位置非常无效。 I've tried a hack to use such function only in one place, put the result in a variable and in all other places use the variable but it leads to angular smth like "variable is updated after it was used" error. 我尝试过一种hack方法,仅在一个地方使用这种功能,将结果放入一个变量中,而在所有其他地方都使用该变量,但是它会导致角度模糊,如“变量在使用后被更新”错误。

Is there any better approach to the problem? 有没有更好的方法来解决这个问题?

For starters you should use reactive forms. 对于初学者,您应该使用反应形式。 It makes it easier to track changes and manage controls. 它使跟踪更改和管理控件变得更加容易。

With that in mind, start by creating a default value for your form : 考虑到这一点,首先为表单创建一个默认值:

defaultFormValue = { firstName: '', lastName: '' };

Then create a form from it : 然后从中创建一个表单:

this.myForm = formBuilder.group(this.defaultFormValue);

Now you can use all of the reactive forms methods & properties to manage your form 现在,您可以使用所有反应式表单方法和属性来管理表单

get isFirstNameChanged() {
  return this.myForm.get('firstName').dirty;
}

get isFirstNameDifferentThanDefault() {
  return this.myForm.get('firstName').value !== this.defaultFormValue.firstName;
} 

resetForm() {
  this.myForm.reset(this.defaultFormValue);
}

// etc. 

I second Maryannah's idea of switching to reactive forms, with the addition of subscribing to the form's valueChanges Observable (or that of any form control) and using RxJS operators as required. 我赞同玛丽安娜(Maryannah)切换到反应形式的想法,另外还订阅了表单的valueChanges Observable(或任何表单控件的值),并根据需要使用RxJS运算符。 For example: 例如:

// watch first name field for changes
this.userForm.get('firstName').valueChanges.pipe(
    debounceTime(300),
    distinctUntilChanged()
).subscribe(newFirstNameValue => {
    // do stuff with new value here
});

// watch whole form for compound checks
this.userForm.valueChanges.pipe(
    map(formData => { 
        importantCheckbox: formData.importantCheckbox,
        desiredInput: formData.desiredInput
    })
).subscribe(formData => {
    // react to compound check here
});

RxJS is incredibly powerful in this kind of situation. 在这种情况下,RxJS非常强大。 Definitely something to look into. 绝对值得研究。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM