I have a custom element on my page and need to access a variable on the app.js from the custom element. Is the only way to bind the data I need to the custom element?
<custom-element data.bind="data"></custom-element>
The reason I ask is that I am running a loop to create multiple custom-elements and don't want to bind 5 variables to each custom element like that. Just asking if there is another way?
A custom element's template cannot access the outer scope. This is by-design. It ensures custom elements are portable. This mirrors the way standard elements work such as <div>, <a>, etc. You can use those elements anywhere. The only way to pass them data is via their attributes.
If you want to tightly couple your custom element to the outer view model, you could do something like this:
<custom-element app.bind="$this"></custom-element>
but this is not recommended
I'm a beginner in AngularJS, I understand most of the mechanics but I'm still grasping the "culture".
I'd like have clean separation between my HTML, DOM, data and communications.
My impression of a controller is a module that implements a "data" model, but is void of UI semantics (i.e. DOM manipulation).
However in my HTML, if I use an ng-click it is the controller's scope that is accessed for the click function implementation, which more then likely will need to call back into the DOM.
So where should I implement my click functions if I do not want DOM manipulation in my controller? Are DIRECTIVES the universal answer to this?
Suppose I have 2 controls on a page that need to interact with each other, should I create a directive on the parent of those controls parent that implements the click functions of both child controls? Or perhaps create a directive for each control and possibly pass the ID of the other control as an attribute? OR maybe a directive for the parent AND children?
--------- UPDATE 1 -----------
The following HTML is a simplified and contrived example that [hopefully] illustrates my question.
<div id="searchComponent">
<input id="txtSearchText" ng-keyup="..."/>
<input name="Go" id="btnDoSearch" ng-click="..."></input>
<div id="autoCompleteResults"></div>
<div id="fullResults"></div>
</div>
As the user types in the txtSearchText, the autoCompleteResults is populated, factoring in the usual minimum characters and timouts.
When the user presses or clicks the btnDoSearch, the autoCompleteResults is cleared/hidden and the fullResults is populated.
Finally, if the user begins typing new txtSearchText, the fullResults would be cleared/hidden and the autoCompleteResults is again seen with results.
Any guidance would be appreciated!
So where should I implement my click functions if I do not want DOM manipulation in my controller? Are DIRECTIVES the universal answer to this?
DOM manipulations, in my opinion, means something like document.querySelector(), addCliss, etc. ng-click is the event, which is supposed to deal with some business logic. Put it in the controller is fine.
Of course, directive is your another choice. directive is usually used to extract some reuseable components, such as modal, across different pages. If you repeat some code in different controllers, consider extracting them to directives or service.
Suppose I have 2 controls on a page that need to interact with each other,...
In short: use service, which is designed for that scenarios.
The general philosophy is to reference the DOM explicitly as little as possible. Most (if not all) things you want to do can be done by binding an aspect of you HTML element to a property on $scope, and manipulating that property. So you never have to do some like "Change the class of <span id="foo"> to red now that isRed is true". Instead you would have <span ng-class="{ red: isRed }>". So if you have two click handlers that share information, it's perfectly valid to have them change some common variable in your controller, and have state of the UI accordingly with DOM bindings. Directives are used more for reusing DOM elements, or when you do have to explicitly refer to DOM elements, i.e. adjusting the scroll properties of a div. You could use a directive to add the same click handler to many elements for example. Services can be used to share information, although if both of the controls belong to the same scope there's less of a reason to do that.
I would like to create a directive that is similar to a control. It should be able to be instantiated from "anywhere" and I want to call functions on it's scope from a parent scope/controller.
A very easy example would be:
I have a special directive called myContactForm (which can be used in different places and pages). Now this myContactForm, in it's templace, uses the directive myEditControl. myEditControl is, when you look at the template nothing but an input and a button and in the scope has the function "clear()" so you can delete whatever is inside the input and maybe other functions.
Now when something happens in myContactForm (for example a button is pressed or a broadcast is received or whatever) I want to call "clear()" on the myEditControl that's inside it. Just like it was a normal control.
How would that be done?
I know about the require but that only works for parents and I would have to know the Controllername of the Directive that uses myEditControl. Instead I want any View/Controller to be able to use myEditControl. And I cannot require the myEditControl-Controller from myContactForm because it is a child not a parent.
What is the technique used in angular to solve these kind of problems?
My idea was to transmit a callback or "myContactForm"-Scope to the myEditControl with an attribute so the myEditControl can "register" itself on the parent and the parent then saves that controls scope for later reference and calling of functions. This seems very hacky though....
I have this extend text component which can add auto complete, tagging, and search query capabilities to a input/textarea (which can work independently or together). Instead of having all the functionality included in one big directive, I would like to move the auto complete, tagging, and search query functionality into there own directives in order to make changing or replacing them easier. Any type of communication that needs to happen between them I imagine would be done through the directive controller's.
The a small prototype on how I plan on doing this is here:
http://plnkr.co/edit/836sPtrBt4XXOeDI8mLf?p=preview
Where the element must have the extend-text attribute but then can also optional have any of the et-auto-complete, et-tagging, or et-search-query.
Is this the angular way of separating this type of functionality for directives?
I have a recursive directive the compiles an HTML element and appends to the DOM structure. The input data I get is the JSON tree. I want to augment the tree to do some pre-processing and set a watch on the tree.
How can I do this considering I want the directive to be reusable?
Can I attach my own controller to the directive scope and do it there? Or maybe post vs pre link function?
Edit : Consider this way of printing a tree. This approach indents the data using css to give the effect of a 'recursive' template but does not use recusrion. If you look at the js file, it actually loops through the JSON data, add parameters to it and applies a $watch on it to notify for the click event.
On the other hand, consider the angular way of using a $compile for runtime DOM manipulation. This approach is very good. I want to modify this method and add parameters to the JSON data before the directive is actually applied. While this should be trivial to do in the application controller, I want to create a reusable directive that can work out of the box like the first approach.
Hope this brings clarity.