AngularJS: Connecting data to model in a directive - javascript

My intent is to have some data displayed on a page and have any changes to it reflected in the model. However, the data needs to have specific manipulations applied before display, and remain connected to the model.
For example, if the data is an html fragment, I'd be wrapping it in a DIV with attribute contentEditable. However if it's a set of options, I'll be wrapping it in a UL and LIs, each of which containing a SPAN with attribute contentEditable.
In each case, the contentEditable part should remain connected to the model.
I'm working on a JSFiddle to try to make some inroads (starting with the case where the item is an html fragment) and have labelled points (2) and (3) where I'm currently stuck. Trying to:
a) Get the watch function to notice a change to the content
b) Maintain the two way binding between the displayed editable content and the model
My fiddle is here: http://jsfiddle.net/rAXmV/
Any suggestions for how I could approach this would be much appreciated.
Edit
I've been looking into using $compile to generate the output structure and it does look like it is getting the relevant data passed in. However it's still disconnected from the model:
http://jsfiddle.net/xRQ7M/
Edit 2
After some more hacking I have a working implementation for the contenteditable areas within the supplied HTML. It picks up the changes on focusout, which is the only way I could find that bubbled up from contenteditable areas within the processed html.
A more permanent JSFiddle is here: http://jsfiddle.net/donovanh/q6auY/

You can use the ngModelController directive to modify the data in a model and keep the data binding of the model.

Related

Why does the value attribute from an input[text] is different from what the browser renders?

I'm getting this strange behaviour in a very specific set of inputs on one my applications. I create some inputs and I can see them as I created them on the Elements panel (google chrome), but the way the browser renders it is different.
Note how the input is renders with comma instead of a point, but the value attribute uses a point
When I get a referente to that element using the selector API, I get this:
A direct reference to the Dom Element will return 11,00. The tag has 11.00 and jQuery returns the 11,00. I've removed all js that interacts with this element (masks, events, etc) and the issue still happens.
I've been swearing at the DOM for a day and a half, but I know this is most probably an issue with my application. What bothers me the most is that the browser does not honor what I see in the elements panel.
This is the small piece of code that creates the element, stopped right before the tag is created. Note the variables values in the right panel:
Could someone give me a hint about what could be causing this difference in between element, view and attributes? If possible, I'd like to know what/how this is happening in depth.
Thank you in advance

How can I put content from my index.html into my view.html?

I have something like this plunker. I would like my view to get populated with the mapId that gets passed into the directive. Then I would like to show that view in place of "This is some content".
First how can I pass the mapId into the view and secondly how can I then show that view in the lightbox div?
I know this is kinda vague but I'm new to angular so I don't know what other information is needed here.
You're not going to be able to use the view.html file with the current lighbox code. It would need to be heavily modify to make use of template files and isolate scopes. However, you can use the current code to achieve the same thing with perhaps the addition of a controller to modify the scope.
I've modified the index.html in the plunker so that it displays the mapId value.
Let's go over what angular-lightbox is actually doing:
By returning just a function, the directive is going through the whole compile process and then using the returned function as the linker. The linker then goes on to (depending on the options) add an overlay (the opaque dark background of the lightbox) to the DOM & then add the lightbox active class to div#lightbox. This div is already in the DOM, but hidden due to the CSS, and has been already compiled & rendered by AngularJS so it can't really be changed other than through two-way data binding at the same or child scope level.
What my changes did:
I added a bound scope variable to div#lightbox called mapId and added an ng-click to the buttons that sets the value of mapId to 1, 2, or 3. So when you click on the button, div#lightbox is revealed & the value of the new value of mapId is shown.
Given that the above is probably not what you want to accomplish...
Let's talk about how to go about doing that
First you will need to load view.html into the directive somehow. Either by just having the view.html contents be a string inside the directive or use $templateCache.
You will then need to $compile the HTML from view.html, passing in a new scope that contains the values you want from options, and then append it to div#lightbox.
I would use a modal from Angular-UI bootstrap http://angular-ui.github.io/bootstrap/, and adapt it for my case. I think this is a good starting point.

What are the best practices for creating new elements of different type in Angularjs?

I have a list of elements of different types. Each has a toggle which toggles their visibility. Now there are two ways to hide an element either detach it from DOM or set the visibility to hidden.
As I understand Angular still updates hidden elements so this may impact the performance. Is this true? With jQuery one can detach the element from DOM and then attach it again when it needs to be visible. But is this approach even a good practice in Angular?
From reading Angular documentation and its API it gave me an impression that Angular prefers that all templates/HTML are declared at the start and their content is dynamically changed with controllers. So if you want to add/remove elements you'd use an ng-repeat directive and then by removing elements from an array in the scope you can add/remove elements from the template. This works well with primitive elements of the same type. However, how does this work if you have a list of elements of different type?
Edited:
http://jsfiddle.net/k26bA
An example here would be a list of tools which can be made available with a checkbox. In the example the first approach has a static list of elements which can not be dynamically changed. Which means you need to know in advance which tools will be available.
The second approach has a list in the controller to which you add and remove tools and in the template use ng-repeat to iterate over that list and create the tools. However, I'm stuck here as a tool can be a button, a text field, checkbox or even a complex div.
I find it a little hard to have a model first here because this is just a part that hides and shows available controls as opposed to displaying a domain model.
A good example of what I'm thinking would be Google Maps where you can hide or minimise various controls on the map.
You probably need to familiarize yourself with the ng-switch directive. The inactive items in an ng-switch are entirely unhooked from the DOM, as opposed to an ng-hide or ng-show, which simply set the CSS styles to show or hide.

Kendo TreeView: Can you edit a single dataitem without full tree update?

I'm currently running with kendo v2012.3.1315 and I am trying to edit a specific node in a tree view without a full tree view update.
I would like to be able to edit the name and have it reflect on the tree and any access to dataitem. Right now, I have been able to just overwrite the html but a) this could change due to template changes and b) when i access the dataitem later, it still has the old text.
The reasoning for this desired functionality is two fold: performance and consistent user interface.
Does anyone know if this is possible?
Thanks.
Find the element in the tree and update its .html() to the same value it would have if you would redraw the tree.

is it possible to view one html element twice on the same page, or must I create a duplicate?

I am creating a site that allows viewing and editing the contents of the 'src-div' contents within the 'edit-div.' I am not editing the src-div directly, because its thumbnailed using css zoom property.
I have considered using knockout.js to bind both elements to an observable. Currently, I have implemented the feature with jquery .html() function: simply set edit-div innerhtml to src-div innerhtml on 'select', and reverse the process after changes are made to edit-div to update the src-div.
I am wondering if I really need 2 divs here, or if there is some way to actually view the same element twice on a page, and any changes made will automatically reflect in both 'views,' elimiating the need to copy innerhtml property back and forth between two elements.
essentially, this is like a mirror effect, without the flip.
the closest thing I found so far is:
http://developer.apple.com/library/safari/#documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Reflections/Reflections.html
Any recommended practices for performing this task are appreciated.
(Almost) everything you see on a page has a counterpart in the DOM. Everything in the DOM gets exactly rendered one time (apart from pseudo-classes). And every node in the DOM can only have one parent (no exclusions).
Unfortunately you'll have to clone the specific node and add changes to both, as there is no copy & translate mechanism in the current CSS documentation.
If you're using jquery you can use one div and "clone" it. You can read this for more information.
http://api.jquery.com/clone/
If you set the class of the div to the same thing, you can have changes propagated to both. Then you can apply .addClass to the second div to apply a "reflected" affect (if that's your final goal).

Categories