Rebind data in child component when updates (AureliaJS) - aurelia

I have a component which has a grid-child-component. I pass the data to the grid from the parent:
<grid data.bind="data"> </grid>
After the data is updated in the parent, I also need to be refresh / rebinded in child. Currently, it is not.
data is an object:
data: {items: myType[], otherData: number}
How could I achieve that?
Thanks in advance!

I reply myself, as the problem was not related to "rebind" child data. I had a class.bind="getClassByStatus(item), where item = {status: string, anotherStuff: any} Well, what actually updates is item.status not item itself, so, class.bind does not observe status attribute but item, and item is not being changed.
So, it was my fault in understand how class.bind works.

Related

Vue2 $emit not firing the callback

Using Vue2, I have a list of books on a page where the details are shown via a child component. The user can delete one of the books from within the child component. I want the list to update after the delete. I'm using an $emit from the child after the record is deleted from the database. I can see from the console that the $emit is sent with the correct new list of books in the payload. However, the callback function in the parent isn't being fired. I can tell because the console.log I have at the beginning of the callback isn't showing up in the console.
Any suggestions on what I'm doing wrong?
Here's what's in the parent:
<div v-for="book in books" :key="book.BookID" #book-refresh="refreshbooks">
<BookCard :book="book" />
</div>
Here's the callback function:
async refreshbooks(newbooks) {
console.log('in books.vue, starting refreshBooks, newbooks is: ', newbooks)
this.$set(this, "books", newbooks)
.bind(this)
},
Here's what's in the function (in the child component) that fires the $emit:
async deleteBook(bookID) {
this.dialogdelete = false
await (EventService.deleteBook(bookID, this.user.UserID))
.then((newbooks) => {
this.$emit('book-refresh', newbooks)
}
)
},
TJ, thank you for the suggestion. I did as you said and created the mre which worked. I then went back to see what was different. The only things I changed were the name(s) of the functions. I changed the book-refresh and refreshbooks all to a simple refresh. Now it works perfectly. I haven't taken the time to see if I just didn't have the names matched up properly or if there's just something about hyphenated names? I did read somewhere yesterday that mixed case makes a difference, so maybe? In any case, keeping it super simple has helped me to move on.
Thanks again for helping me see the forest instead of the trees!

Vue.js - access to data from slot's component

I have a problem with accessing data from the component using slots.
Here's my code:
codepen.io/anon/pen/BbOEZz
I want the line:
<p slot="desc">{{ desc_01 }}</p>
It started working and at the slot in the template displayed the value with date.
Can anyone help me with this matter?
There are a couple of mistakes in your code
1.You don't access data directly from the child. The child communicates with the parent via events, using emit.
You should
fire an event from the child
listen to the event on the parent
update a variable on the parent.
2.There is no desc_01 declared on the app. The template is executed in the context of the app and not the child, so you also need to define that property.
data () {
return {
desc_01: ''
}
}
I've added a code pen for this here.

Can I do "special subscribe" to one of the properties in Vue2?

I have view component that displays info about RECORD. This component contains contains some properties for description of user interactions with view (let's say it is lastPushedButton). So I need to reset this lastPushedButton property when view is receiving new RECORD's model. I have tried to use updated event but then it resets lastPushedButton everytime something changed, not only RECORD.
What is the right approach?
I assume your record is passed in via a property to your component?
What you probably want is a watch on your property variable: https://v2.vuejs.org/v2/guide/computed.html#Watchers
watch: {
record: function (newValue, oldValue) {
this.lastPushedButton = ''
}
},

Delete a Vue child component

I'm really stuck on this one.I have created a Vue (2.0) component that is made up of child components, it's all being Webpacked etc. For example, this is the parent:
<div>
<h1>This is just a title for lulz</h1>
<rowcomponent v-for="row in rows" :row-data="row"></rowcomponent>
</div>
which has a prop of rows passed to it which looks something like this:
rows: [{ sometext: "Foo"} , { sometext: "Bar" }]
So my row component looks like this:
<div>{{ this.sometext }} <button #click="deleteRow">Delete Row</button></div>
And I feel like it should be really easy to set a method on the rowcomponent that is something like this:
deleteRow() {
this.delete();
}
Do I need to $emit something to the parent with the index of the row in it to remove it? It's driving me crazy. All the examples seem to suggest it would be easy to do, but not in the case where you have child components that want to delete themselves.
Yes, the child component cannot delete itself. The reason is because the original data for rows is held in the parent component.
If the child component is allowed to delete itself, then there will be a mismatch between rows data on parent and the DOM view that got rendered.
Here is a simple jsFiddle for reference: https://jsfiddle.net/mani04/4kyzkgLu/
As you can see, there is a parent component that holds the data array, and child component that sends events via $emit to delete itself. The parent listens for delete event using v-on as follows:
<row-component
v-for="(row, index) in rows"
:row-data="row"
v-on:delete-row="deleteThisRow(index)">
</row-component>
The index property provided by v-for can be used to call the deleteThisRow method, when the delete-row event is received from the child component.

ComponentQuery for a parent with ExtJS4?

Is there a way to query "up"? I'm in a Component and want to register listeners to it's parents events with control(). This requires a Query which gets me the parent of my main view.
In ExtJS4, you can use 'up()' from an Ext Element.
The params are a string of the parent element you wish to find e.g:
var parentEl = Ext.get('childID').up('div.parentClass');
If you provide some details about the structure of your components/elements I can give a specific example which should fit.
EDIT: To show going 'up' from a component
var myComponent = // however you've got it
var theParentEl = myComponent.getEl().up('div.parentClass');
Usually up('PARENTCLASS') is enough for what you're trying to do. Here is what I do all over the code so elements generates event for the form they are in:
items: [
...
{ xtype: 'checkbox', listeners: {
change: function() { this.up('window').fireEvent('checkboxchanged'); }
}}
...
]
As I understand, you want to listen to events dispatched by a component's parent from the child component's controller control function specifically.
There is not a query selector like 'parent < component' which you can put in the child controller's control function to listen to parent events.
Normally I would just add the parent view to the child's controller, then you could listen to it's events. But I assume you are not doing this because you are trying to delegate to different controllers or something.
You could fire an event in the child component whenever that parent event occurs. Inside the parent controller you could do it like this:
var child = parent.down('child');
child.fireEvent('myOwnEventName', arg1, arg2, arg3, etc);
Then you would add a handler for 'myOwnEventName' in the child controller's control function to run the logic you wanted for it.
If the parent doesn't have a controller then you should just add the parent component as a view in the child's controller.
The Sencha help says "Member expressions from candidate Components may be tested. If the expression returns a truthy value, the candidate Component will be included in the query:" in the http://docs.sencha.com/ext-js/4-0/#!/api/Ext.ComponentQuery help.
Took me a while to realize I can do the following in my controller:
this.control({
'window{down("testcomp")}[down]': { beforedestroy: this.doNotCloseIfUnsaved }
});
Using the {} operation, we can call any arbitrary code. Really bad from an efficiency standpoint, but it got the job done. I had to add the [down] because it runs component queries from right to left, so we have to be sure down() exists before we try running it (on every component). Thus, I was able to attach an event to whatever window holds my component.
Of course, other functions can be used too, like child() instead of down() if you want to ensure it is the immediate child rather than just anywhere below.