Differences on someArray.[] and someArray.#each - javascript

So I understand that Ember can compute on an array and elements within it. There are two options here.
someArray.[] and someArray.#each
If say I changed one of the element in array and there is a computed property that depends on it. Which one should I use? Thanks.

someArray.[] will only be used when the array items are added/removed.
When the particular property in the array object is changed then someArray.#each will be called.
isNameChanged: function() {
console.log('is Name Changed')
}.property('someArray.#each.name')
Can check this Ember.js: Observing array property using #each doesn't work

Related

Observe change of object proprty in nested array in Ember.js

We have this data structure
[[{foo:"12", bar:"34"}, {foo:"33", bar:"55"}], [{foo:"45", bar:"67"}]]
How is it possible to make a computed property to observe a change on foo or bar?
Normally you use .#each.someProperty in a computed property to watch specific object properties in an array but in the case of nested arrays (or nested objects), you can't do .#each.#each.someProperty because .#each only works one level deep.
You need to use intermediary computed properties to raise the inner objects up one (or more) levels and have another computed property watch these in turn. There may be other ways to wire things up, but this is a pretty straightforward way to do it.
Here's a twiddle that demonstrates it. If you open the console you can see the individual computed properties recording a change occurring.
You can also use an alias to pull the inner arrays / objects up a level or two.

Vuejs2: How to re-render array computed properties when array changed

I have array named List and created computed property computedList for him.
When i update value of array it's not showing in html, but in console i see thar array is updated.
`https://jsfiddle.net/apokjqxx/69/`
What is best way to use computed properties for array?
Maybe is exists way to trigger to re-render computed property?
Due to limitations in JavaScript, Vue cannot detect the changes to an array like this: this.list[1] = 'vueman'
You have to use Vue.set or vm.$set as explained here to trigger state updates in the reactivity system, like follwoing:
this.$set(this.list, 1, 'vueman')
see updated fiddler here.

What does this code using [].filter.call do?

I’m learning javascript and trying to write code that sorts a list, removing elements if they meet certain criteria.
I found this snippet that seems promising but don't have a clue how it works so I can adapt it to my needs:
list = document.getElementById("raffles-list").children; // Get a list of all open raffles on page
list = [].filter.call(list, function(j) {
if (j.getAttribute("style") === "") {
return true;
} else {
return false;
}
});
Can you guys help me learn by explaining what this code block does?
It's getting all the children of the "raffles-list" element, then returning a filtered list of those that contain an empty "style" attribute.
The first line is pretty self-evident - it just retrieves the children from the element with id "raffles-list".
The second line is a little more complicated; it's taking advantage of two things: that [], which is an empty array, is really just an object with various methods/properties on it, and that the logic on the right hand side of the equals sign needs to be evaluated before "list" gets the new value.
Uses a blank array in order to call the "filter" method
Tells the filter to use list as the array to filter, and uses function(j) to do the filtering, where j is the item in the list being tested
If the item has a style attribute that is empty, i.e. has no style applied, it returns true.
Edit:
As per OP comment, [].filter is a prototype, so essentially an object which has various properties just like everything else. In this case filter is a method - see here. Normally you just specify an anonymous function/method that does the testing, however the author here has used the .call in order to specify an arbitrary object to do the testing on. It appears this is already built into the standard filter method, so I don't know why they did it this way.
Array like objects are some of javascript objects which are similar to arrays but with differences for example they don't implement array prototypes. If you want to achieve benefits of array over them (for example like question filter children of an element )you can do it this way:
Array.prototype.functionName.call(arrayLikeObject, [arg1, [arg2 ...]]);
Here in question array like is html element collection; and it takes items without any styling.
list is assigned a collection of elements that are children of the raffles-list element
list is then reassigned by filtering its elements as follows
an empty array is filtered by calling it with the parameter list and a callback function. The formal parameters for call are this (which is the list) and optionally further objects (in this case a callback function)
The callback function receives a formal parameter j and is called for each element
If the element's value for the style attribute is empty the element is retained in the array. Otherwise it is discarded.
At the end list should contain all elements that don't have a value for its style attribute

How to get object from array by object's unique property value?

Basically everything is said with the title: how to get the object from array by object's property value which is unique by the way?
Situation:
My current strategy is that I gave id attribute to the div of that object's property id (all ids are unique, take a look at Array of objects below) which looks like this:
<div id="3590" class="my-div"></div>
Now, when this div is clicked, I'll get the id attribute and I need to find the right object because I also need to get some other properties and also make some changes to some properties.
Why Im doing this:
This seems to be the only way because as I was told in other question that there's no way to access the object, even when this div is one of the object's properties (take a look at Array of objects below).
If that's not true, please let me know. This is super important!
Array of objects:
0: myObject
__e3_: Object
div: div#3590.my-div
gm_accessors_: Object
gm_bindings_: Object
id: 3590
latlng: _.K
map: _.ng
uh: Object
__proto__: c
1: myObject
__e3_: Object
div: div#3591.my-div
gm_accessors_: Object
gm_bindings_: Object
id: 3591
latlng: _.K
map: _.ng
uh: Object
__proto__: c
//thousands of objects
There can be thousands of objects in that array and that's why I added word "fastest" to the question: Im concerned about the performance because there's also other stuff going on.
Also, I prefer vanilla JS because Im currently learning it but if you know a good and fast way in jQuery, please go ahead, I'll convert it myself.
More details:
Objects are in array because I also need to iterate them (more often than working with them one-by-one)
All one-by-one actions are done via click events (user triggered and there's some protection: only one action at a time)
Keep reference to the corresponding object in the element as well.
So, whenever you click an element, the element object itself will have the reference to corresponding object. No need to find from the array.
And yes please be careful with name collisions. Assign object to new key so that object doesn't replace value of element object's existing key.
For old browsers, I am not sure they can even render thousands of elements.
Example:
var element = document.createElement("div");
element.myObj = {id: 3306, name: 'coolBoy'}; //make sure key, 'myObj' in this case, doesn't already exist.
var myArray = [];
myArray.push(element.myObj); //if you need to keep in array as well.
element.onclick = function(e){
console.log(e.currentTarget.myObj.name);
};
I'd recommend using a Map collection - it allows for both fast iteration and fast access by key, and is a builtin data structure.
If you don't want to go down the ES6 route (and not use a shim either), a reasonably fast approach would be to keep the array sorted. You can use binary search to access single elements.
Notice that for a thousand objects, there probably won't be an observable difference anyway. Don't prematurely optimise. Just keep your API to access the collection clean so that you can easily swap out the data structure in the future, should there be any need.
function getObjectFromId(id) {
return ARR.filter(function (obj) {
return obj.id === id;
})[0];
}

How can I get the length of a deferred Model in CanJS?

I am getting a model deferred object with a structure like this:
How can I find out how many objects are present inside this object (in this case, three). If I use Object.keys(myObject).length, it includes the object observer and other data also like _computeBindings,_bindings etc. I have even tried to use hasOwnProperty while calculating the length but its not giving me desired result.
One way I can figure out is to iterate over the index and get the last index value like this:
can.each(myObject,function(myObject,index){
// Get the last index value and put it into some variable
});
Is there an API for this?
can.Map has a keys function that will give you an Array of the keys in your Map and from that you can get how many Objects by checking that Array's length.
Using a can.List as your data structure would also work. The keys in your data are numeric and you need to check the length, all things that can.List is built for.
Try using myObject.attr('length')
The model _data attribute contains a copy of just the model without the bindings. The easiest way to do this is to use:
Object._data.length

Categories