CopyPastor

Detecting plagiarism made easy.

Score: 1.6747618317604065; Reported for: String similarity, Exact paragraph match Open both answers

Possible Plagiarism

Plagiarized on 2021-02-01
by Oleksii Zelenko

Original Post

Original - Posted on 2020-01-01
by Erik Koopmans



            
Present in both answers; Present only in the new answer; Present only in the old answer;

How to properly watch for nested data ``` new Vue({ el: "#myElement", data: { entity: { properties: [] } }, watch: { 'entity.properties': { handler: function (after, before) { // Changes detected. Do work... }, deep: true } } }); ``` another option ``` var vm = new Vue({ el: '#app', computed: { foo() { return this.item.foo; } }, watch: { foo() { console.log('Foo Changed!'); } }, data: { item: { foo: 'foo' } } }) ``` If you want to watch all items in a list and know which item in the list changed, you can set up custom watchers on every item separately, like so: ``` var vm = new Vue({ data: { list: [ {name: 'obj1 to watch'}, {name: 'obj2 to watch'}, ], }, methods: { handleChange (newVal, oldVal) { // Handle changes here! // NOTE: For mutated objects, newVal and oldVal will be identical. console.log(newVal); }, }, created () { this.list.forEach((val) => { this.$watch(() => val, this.handleChange, {deep: true}); }); }, }); ```
More details can be found here https://stackoverflow.com/questions/42133894/vue-js-how-to-properly-watch-for-nested-data/42134176#42134176
## Tracking individual changed items in a list
If you want to watch all items in a list and know **which** item in the list changed, you can set up custom watchers on every item separately, like so:
```js var vm = new Vue({ data: { list: [ {name: 'obj1 to watch'}, {name: 'obj2 to watch'}, ], }, methods: { handleChange (newVal, oldVal) { // Handle changes here! // NOTE: For mutated objects, newVal and oldVal will be identical. console.log(newVal); }, }, created () { this.list.forEach((val) => { this.$watch(() => val, this.handleChange, {deep: true}); }); }, }); ```
If your list isn't populated straight away (like in the original question), you can move the logic out of `created` to wherever needed, e.g. inside the `.then()` block.
## Watching a changing list
If your list itself updates to have new or removed items, I've developed a useful pattern that "shallow" watches the list itself, and dynamically watches/unwatches items as the list changes:
```js // NOTE: This example uses Lodash (_.differenceBy and _.pull) to compare lists // and remove list items. The same result could be achieved with lots of // list.indexOf(...) if you need to avoid external libraries.
var vm = new Vue({ data: { list: [ {name: 'obj1 to watch'}, {name: 'obj2 to watch'}, ], watchTracker: [], }, methods: { handleChange (newVal, oldVal) { // Handle changes here! console.log(newVal); }, updateWatchers () { // Helper function for comparing list items to the "watchTracker". const getItem = (val) => val.item || val; // Items that aren't already watched: watch and add to watched list. _.differenceBy(this.list, this.watchTracker, getItem).forEach((item) => { const unwatch = this.$watch(() => item, this.handleChange, {deep: true}); this.watchTracker.push({ item: item, unwatch: unwatch }); // Uncomment below if adding a new item to the list should count as a "change". // this.handleChange(item); }); // Items that no longer exist: unwatch and remove from the watched list. _.differenceBy(this.watchTracker, this.list, getItem).forEach((watchObj) => { watchObj.unwatch(); _.pull(this.watchTracker, watchObj); // Optionally add any further cleanup in here for when items are removed. }); }, }, watch: { list () { return this.updateWatchers(); }, }, created () { return this.updateWatchers(); }, }); ```

        
Present in both answers; Present only in the new answer; Present only in the old answer;