Angular taking DOM snapshot - dependency-injection

I am trying to record the content of a div which is populated using ng-repeat, sort of like taking a snapshot of that div at certain moments so that I don't have to write more code to persist data.
link: function(scope, element, attrs) {
scope.game = game;
var $element = $(element),
$clone = $element.children().clone();
scope.$watch('someVariable',function(array){
if (array[array.length - 1] === scope.id){
record($compile($clone)(scope));
console.log($compile($clone)(scope));
}
},true);
}
I've been trying variations of code like this but could not get any luck, I've never been able to deep copy the content of the div generated by ng-repeat
any suggestions on how I could copy the exact dynamically genereted content of the div at certain point of time?

If you have the data to present in a ng-repeat you already have the data in the model, you just have to save a snapshot of that data to other object in the Scope. You should manipulate the data in the controller instead of trying to access the DOM directly, this is a big no no in angularjs. Then if you need a Div to reuse, just make a Directive that knows how to present those snapshots you saved in the model.

Related

How to run a specific method when props changes in Svelte3?

I'm building an autocomplete text field component. We will show popup of items filtered based on what users type. It is going to be async, I will get the details from the server and do some filtering based on the text typed in the field.
So here, I have run this filtering logic whenever I send new data to the component.
I come from angular, there we used to have ngOnChange(). Is there something similar available in svelte3.
Right now, I'm filtering by calling the method from outside by binding bind:this. I don't feel like this is a correct approach.
https://github.com/manojp1988/svelte3-autocomplete/blob/master/dev/App.svelte
Without stores, using a prop
Just using a prop:
export let search = '';
....
$: if (search !== '') { // make it react to changes (in the parent)
doSomeThing(search);
};
Stores
Svelte also has stores. A store is an observable object which can be observed everywhere even beyond you project with RxJS.
Example:
const unsubscribe = search.subscribe(s) => {
doSomeThing(s);
});
onDestroy(unsubscribe);
In another component you can use search.set('Hi');
But looking forward for other solutions to handle these kind of changes in parent <-> child components or calling child Component methods.
From child to parent we can fire events.
But from parent to child ...? we can use a store or Component bind:this or ..? but ....

Adding a Value to Collection Items

I want to load data from many files. Each file is named with a date and I need to inject this date to each of the fetched Entries of my file.
I know I could do this with an foreach - loop before inserting the data into the collection, but I think there should be a better solution.
Content of one file
[{"price":"95,34","isin":"FR0000120073"},{"price":"113,475","isin":"CA13645T1003"}]
The Code I use to move the data into a collection.
$collection= collect(json_decode(File::get($file)));
I tried for example the "map" method, however I don't know how to pass an additional variable to the anonymous function.
The content of my collection should look like this:
[{"price":"95,34","isin":"FR0000120073","date":"2016-06-23"},{"price":"113,475","isin":"CA13645T1003","date":"2016-06-23"}]
Is there any simple solution using the collections or do I have to use a foreach-loop?
May be this will help
$collection = collect(json_decode(File::get($file)));
$collection = $collection->each(function ($item, $key) {
//First iteration of $item will be {"price":"95,34","isin":"FR0000120073"}
$item->date = "2016-06-23"; //Insert key, value pair to the collection
});

Dynamic Tag Management - Storing

We're in the process of moving to DTM implementation. We have several variables that are being defined on page. I understand I can make these variables available in DTM through data elements. Can I simply set up a data elem
So set data elements
%prop1% = s.prop1
%prop2% = s.prop2
etc
And then under global rules set
s.prop1 = %s.prop1%
s.prop2 = %s.prop2%
etc
for every single evar, sprop, event, product so they populate whenever they are set on a particular page. Good idea or terrible idea? It seems like a pretty bulky approach which raises some alarm bells. Another option would be to write something that pushes everything to the datalayer, but that seems like essentially the same approach with a redundant step when they can be grabbed directly.
Basically I want DTM to access any and all variables that are currently being set with on-page code, and my understanding is that in order to do that they must be stored in a data element first. Does anyone have any insight into this?
I use this spec for setting up data layers: Data Layer Standard
We create data elements for each key that we use from the standard data layer. For example, page name is stored here
digitalData.page.pageInfo.pageName
We create a data element and standardize the names to this format "page.pageInfo.pageName"
Within each variable field, you access it with the %page.pageInfo.pageName% notation. Also, within javascript of rule tags, you can use this:
_satellite.getVar('page.pageInfo.pageName')
It's a bit unwieldy at times but it allows you to separate the development of the data layer and tag manager tags completely.
One thing to note, make sure your data layer is complete and loaded before you call the satellite library.
If you are moving from a legacy s_code implementation to DTM, it is a good best practice to remove all existing "on page" code (including the reference to the s_code file) and create a "data layer" that contains the data from the eVars and props on the page. Then DTM can reference the object on the page and you can create data elements that map to variables.
Here's an example of a data layer:
<script type="text/javascript">
DDO = {} // Data Layer Object Created
DDO.specVersion = "1.0";
DDO.pageData = {
"pageName":"My Page Name",
"pageSiteSection":"Home",
"pageType":"Section Front",
"pageHier":"DTM Test|Home|Section Front"
},
DDO.siteData = {
"siteCountry":"us",
"siteRegion":"unknown",
"siteLanguage":"en",
"siteFormat":"Desktop"
}
</script>
The next step would be to create data elements that directly reference the values in the object. For example, if I wanted to create a data element that mapped to the page name element in my data layer I would do the following in DTM:
Create a new data element called "pageName"
Select the type as "JS Object"
In the path field I will reference the path to the page name in my data layer example above - DDO.pageData.pageName
Save the data element
Now this data element can be referenced in any variable field within any rule by simply typing a '%'. DTM will find any existing data elements and you can select them.
I also wrote about a simple script you can add to your implementation to help with your data layer validation.Validate your DTM Data Layer with this simple script
Hope this helps.

Dynamically Loading LI's in JQueryMobile 1.0

I've just updated my project from jquerymobile 1.0a1 to version 1.0.
I've encountered a problem with dynamic content. Based on an ajax search I populate an unordered list with list items. Previous the following code refreshed the list so that all the styling appeared correctly:
$('#myContent').find("ul").listview();
$('#myContent').find("ul").listview('refresh');
However as of 1.0 this no longer seems to work.
The list appears but the styling is all wrong and the data-theme on all the elements gets ignored.
Has anyone come across a similar issue with updating and come across the solution.
Updating lists If you add items to a listview, you'll need to call the refresh() method on it to update the styles and create
any nested lists that are added. For example:
$('#mylist').listview('refresh');
Note that the refresh() method only affects new nodes appended to a
list. This is done for performance reasons. Any list items already
enhanced will be ignored by the refresh process. This means that if
you change the contents or attributes on an already enhanced list
item, these won't be reflected. If you want a list item to be updated,
replace it with fresh markup before calling refresh.
http://jquerymobile.com/demos/1.0/docs/lists/docs-lists.html
if #myContent is the listview you can do this:
$('#myContent').listview('refresh');
if #myContent is the page you can do something like this:
$('#myContent').trigger('create');
Create vs. refresh: An important distinction Note that there is an important difference between the create event and refresh method
that some widgets have. The create event is suited for enhancing raw
markup that contains one or more widgets. The refresh method should be
used on existing (already enhanced) widgets that have been manipulated
programmatically and need the UI be updated to match.
For example, if you had a page where you dynamically appended a new
unordered list with data-role=listview attribute after page creation,
triggering create on a parent element of that list would transform it
into a listview styled widget. If more list items were then
programmatically added, calling the listview’s refresh method would
update just those new list items to the enhanced state and leave the
existing list items untouched.
http://jquerymobile.com/demos/1.0/docs/pages/page-scripting.html
What you want can be achieved by replacing your 2 lines of code with the following:
$('#myContent ul').listview('create');
Hope this helps...
I've had this issue. The reason you are getting things all messed up is you are initalizing and refreshing the element multiple times. I noticed I had 2 different functions running that would call .listview('refresh') on the same element. After I took one out the themes and data went back to looking normal. Also are you getting any JS errors?
EDIT:
To be more specific you are calling .listview() somewhere in your code 2 times which is initializing it twice. I would wait to before you page is loaded to run the refresh so you only call it once.
Another thing you could do is check if the element is initialized already or not so you don't do it twice. Just check the element or in some cases the parent to see if the class ui-listview is present.
var element = $('#myContent').find('ul');
if ($(element).hasClass('ui-listview')) {
//Element is already initialized
$(element).listview('refresh');
} else {
//Element has not been initiliazed
$(element).listview().listview('refresh');
}
Just an FYI you can chain those events to look like $('#myContent').find('ul').listview().listview('refresh');
It cand be achived through.
$('#myContent').listview('refresh');
The below snippet shows you to load data from xml and dynamically create a list view.
function loadData()
{
$.ajax({
url:"BirthdayInvitations.xml",
dataType: "xml",
success: function(xml)
{
$(xml).find("event").each(function()
{
$("#mymenu").append('<li>' + this.textContent + ' </li>');
});
$("#mymenu").listview('refresh');
}
});
}
See if this is related to ur question http://www.amitpatil.me/demos/jquery-mobile-twitter-app/ and this one also http://www.amitpatil.me/demos/ipad-online-dictionary-app/
In first example i am using listview('refresh'); method and in second example i am using
$(document).page("destroy").page();

AJAX pattern in Rails for submitting small chunks of data

I have a web page with lots of small images on it. In a typical scenario user clicks on image and expects it to change with a new image.
Requirements:
When user clicks on image, it should be immediately known to a controller in an Ajax way.
Some strings should be passed to a controller when user clicks on image.
Controller does its job and returns another image (which replaces old one).
Along with image controller returns a couple of extra strings (such as completion status).
Web page updates old image with new one and also updates other parts with these new strings.
Number of images on a page varies but potentially it can be a couple of dozens.
Question: What Ajax technique should be used here? I'm quite new to Ajax and don't feel solid with patterns. Should it be Json or something else?
Any code example would be very very welcome and helpful.
Thank you.
Well it sounds like you need a Event observer on the image object. On that image object, you could have various custom attributes, such as imageid="2", etc. With the element being observed onclick, you'd read the attributes of the elements and pass them on to an AJAX call. I'm not sure if the image is known by the database or would it be available on the page itself. Maybe a back/previous button? In either case, the AJAX call could either return JavaScript directly which then gets parsed to update the DOM and replaces the image with the new image source, or it could return a JSON response which then needs to get read and parsed by the AJAX callback and then updates the DOM. Easiest being to return JS code which gets parsed, but I prefer to have all my JavaScript in one file and not have it all over the place mixed with server side code.
It really depends on what AJAX library you are using.
With jQuery, you might do something like this.
$("#buttonImage").click(function () {
var imageid = $(this).attr('imageid');
$.getJSON("/controller/get_image/" + imageid,
function(data){
$("#buttonImage").attr("src", data.imagesrc);
});
});
And your /controller/get_image/123 would return a JSON response like...
{ 'imagesrc' : '/my/image.jpg' }
As far as I known, the only browser-safe way to change an image is by assigning a new URL to it's src attribute. If you return an image to a request that pass some parameters, it might prevent client-side cashing of the images. For these reasons, I would treat separately the transfer of textual data and images.
The completion status can always be return as the HTTP status text but if more information is needed from the server, you can always return it in JSON or XML, the simplest being JSON.
The responsiveness could be improved by preloading images on the mouseover event.

Resources