I am trying to use the pure.js templating engine to convert a JSON array into HTML code.
I understand how to use autoRender() to map an associative map to HTML: http://jsfiddle.net/P7H98/
but if I replace the associative map with an array, I end up with iteration that inserts empty rows: http://jsfiddle.net/P7H98/1/
Is it possible to autoRender() an array and end up with the same output as the first example?
UPDATE: Nesting <div class="toString"></div> inside the <li> node fixes the problem. But I'm still not sure why. Surely there is a more readable solution to this problem?
The toString is a coincidence.
The property names triggers a loop, because it points to an array.
Then the toString is a method that exists for each array element, and is called.
If you add the class toString on the LI, it will work.
You should try using render and directives.
They can be generated on the fly, and give you a more precise control of what needs to be done.
Related
At the moment I am storing a few objects in Firebase. After successfully retrieving the items from Firebase and storing them in a firebaseArray, I want to further thin out the unwanted elements by deleting the elements in the firebaseArray that do not have the desired property. Consider my code at the moment, that does not do as wanted, however there are no errors in the console:
var querylatestPosts = firebase.database().ref("Topics");
$scope.latestPosts = $firebaseArray(querylatestPosts);
console.log($scope.latestPosts) ;
$scope.latestPosts.forEach(function(el) {
if ($scope.checkWorldview(el) == false) {
delete $scope.latestPosts.el ;
}
});
(Note I am unable to log 'el' in the console, nor does the forEach seem to execute, as I can log nothing in the function in the console)
The 'checkWorldview' function behaves as expected when elements are fed in different instances and returns false if the required property is not present in the element under consideration. Thus if the function returns false, I want to delete the specific element in $scope.latestPosts that does not contain the wanted property.
I hope this is clear, thank you in advance for any help you can offer!
The way you are using the $firebaseArray isn't recommended by the docs (see here), which state that $firebaseArray is read only and should not be manipulated.
So you have a few options:
Instead of filtering the array on the client-side, you should modify the query you're using to retrieve data from Firebase to only get elements that have the desired property (ex: use 'equalTo' in the query)
OR
Don't use a $firebaseArray because you're not using it in the way it was intended. Use a regular, good ol' fashion JavaScript array instead.
** Also, just a general comment: don't delete elements from an array as you loop through it as this is generally bad practice (we don't expect arrays to have elements added/removed while we loop through them). Instead, use Array.filter.
I'm confused why reverse() works for regular arrays but not d3.select objects, which are based on the array as well. I'm basically trying to traverse the elements I selected from the DOM in reverse order via each but the following seem to traverse them in the same order:
d3.selectAll('.someclass').each(function(){console.log(this);})
d3.selectAll('.someclass').reverse().each(function(){console.log(this);})
I figured it out. d3.select IS an array, it's in their documentation (https://github.com/mbostock/d3/wiki/Selections), but it's a container array of size 1, the actual array of DOM elements is contained within that first element. The following, while a bit uglier, works as expected:
selection = d3.selectAll('.someclass')
selection[0].reverse()
selection.each(function(){console.log(this);})
I'm not a big fan of using the sort solution (the elements are technically already sorted, and I'd also need to figure out the current order in the DOM tree to compare by).
There is no .reverse() method in D3. Note that selections are not arrays and come with their own implementation of methods to manipulate them. To sort the elements in a particular way, use .sort().
The Linq-For-Javascript library contains functions that convert between "jQuery objects" and "Enumerable objects": toEnumerable() and TojQuery(). Consider the difference between these two lines:
$('tr'); // returns array of tr
$('tr').toEnumerable().TojQuery(); // returns array of tr[1]
Converting from jQuery to Enumerable and back to jQuery does not give you what you started with. The end result is an array of arrays of elements, with each sub-array having a length of 1. I do need to make use of Enumerable, so this is just a convenient example of my problem.
This means that to get the id of an element, you'd need to do the following:
$('tr')[0].id; // returns "myID"
$('tr').toEnumerable().TojQuery()[0][0].id; // returns "myID"
I'm surprised of this, because even though I've allegedly gone back TojQuery(), the object returned by TojQuery() does not work with typical jQuery calls:
$('tr').find('td').length; // returns 170 (in my case)
$('tr').toEnumerable().TojQuery().find('td').length; // returns 0 (BAD)
I would like it if both lines returned 170, but apparently Linq-For-Javascript doesn't work that way.
So, my questions:
Why is this?
Am I doing it wrong?
If not, any good workarounds? (convert array of 1-element arrays to array of elements?)
Thanks!
JQuery handles operations according to types. In the first line of the code, if finds all HTML TR objects and by the help of this information it can attach necessary functions to the found objects.
$('tr').find('td')
However, it could not understand after you change it to enumarable object since it is no longer seems to be a HTML Object instead it becomes any other type of object. Thus, jquery cannot attach a function to it.
$('tr').toEnumerable()
here is an example in jsfiddle.
I want to know if I can append a javascript object to innerHTML, that get that object again from innerHTML as object.
something like,
alert((this.innerHTML).html);
that's just an example, don't ask me why do you need this?
I'm trying to edit an existing code, and I have to do this so.
I have to transfer an object via div.innerHTML.
Check this jsfiddle. In it, I add the object to the div as a 'data-'-attribute, using JSON to convert it to a string. After that, adding some comment to the div triggers the DOMSubtreeModified-handler, in which the 'html'-part of the object is retrieved and alerted. It that something to work with?
In this case, quite possible your only option is to convert your object to string and then put that into the element. (This is done by looping through the key, values building the string as you go.)
You would reverse the process to convert it back into an obj.
I know some javascript libary's have helper functions to make this process very simple.
You could try adding the data directly onto the dom element, rather than as its content..
tempDiv.objData = myObject;
It was suggested to use JSON, but no code. So:
function addObjAsJSON(el, obj) {
el.setAttribute('data-myJSON', encodeURIComponent(JSON.stringify(obj)));
}
function getObjAsJSON(el) {
return JSON.parse(decodeURIComponent(el.getAttribute('data-myJSON')));
}
That should allow you to add anything as a serialised object, then get it back. You should add some error checking to make it robust though (e.g. check that you get a string back from the call to getAttribute).
For user agents that don't have built-in JSON support, see json.org which has a link in the javascript section to json.js.
I have an array called as wcs declared using var wcs= new Array();.
I do add items like this, wcs[indx] = value. where i will keep on changing the indx value, so at times, my array will be looking like this
wcs[2] ='a'; wcs[5]=')';
when i call the splice method on this array, all the created indices are re-indexed, meaning they become reset from 0...
how to avoid this in javascript & jQuery
Write your own splice method that works the way you want. If you specify the input, processing and expected output, you might get some help with that.
If you simply want a copy of the array, you may be after the concat method.