Reputation: 14863
Is it possible to bind an element to a scope variable?
I imagine something like that:
<div ng-controller="myCtl">
<span ng-scope-bind="myHelloSpan">hello</span>
</div>
app.controller('myCtl', function($scope) {
$($scope.myHelloSpan).fadeIn(100);
})
I couldn't find anything in the docs.
Upvotes: 1
Views: 4167
Reputation: 449
This is not the Angular way to do it.
A controller should never change the DOM (HTML). That should be handled by a directive. Your controller is supposed to manipulate your business logic and change scope variables and then your directives watch these variables and trigger changes to the DOM/HTML. This is how the core directives (like ng-show, ng-repeat, ng-href etc.) works.
Read more about creating your own directive at https://docs.angularjs.org/guide/directive#creating-directives
If you really, really want to do this (though I recommend you do not!), here is a very simple directive that should do what you want:
app.directive('myScopeBinding', function () {
return {
link: function ($scope, element, attr) {
var myScopeVariableName = attr.myScopeBinding;
$scope[myScopeVariableName] = element;
}
}
});
This directive will allow you to assign a DOM element to a scope variable:
<div ng-controller="myCtl">
<button type="button" ng-click="myCustomFadeTrigger();">Click to fade in hello span</button>
<span my-scope-binding="myHelloSpan">hello</span>
</div>
and it can be used in your controller like this:
app.controller('myCtl', function($scope) {
$scope.myCustomFadeTrigger = function() {
$($scope.myHelloSpan).fadeIn(100);
};
})
The problem with this is that the controller creates the scope, so by the time your controller executes, the directive has not beed assigned to the scope variable. This is why my example uses a button. It could also be used with a timeout, to let the span-directive assign itself to the scope.
Another issue with this is which scope the element is assigned to. If used inside an ng-repeat, it will be assigned to the current iteration. If used inside another directive with its own scope, it will be assigned to that scope, and not necessarily within the controller scope.
THE ANGULAR WAY TO DO IT is to create a directive that does the stuff for you based on some scope variable or event.
app.directive('myDirective', function () {
return {
link: function ($scope, element, attr) {
// Get a jQuery-wrapper only once
var $element = $(element);
// Listen for a scope event
$scope.$on('myCustomEvent', function() {
$element.fadeIn(100);
});
// Watch a variable
$scope.$watch('myElementVisible', function() {
if ($scope.myElementVisible == true) {
$element.fadeIn(100);
}
else {
$element.fadeOut(100);
}
});
}
}
});
And the HTML to use this directive:
<div ng-controller="myCtl">
<button type="button" ng-click="test1();">Click to fade using event</button>
<button type="button" ng-click="test2();">Click to fade using variable</button>
<span my-directive>hello</span>
</div>
Upvotes: 1
Reputation: 69
I would also like to know the answer to this question. Let me try to rephrase it to improve clarity for anyone who knows how to do this:
I have a javascript array of objects called arr
. In the HTML document, I'm using ng-repeat
to make one intl-tel-input element per object in arr
. Now, I need each of the objects in arr
to reference its associated input element on the DOM, so that I can use logic like this:
for (var i = 0; i < arr.length; ++i)
foo(arr[i].domElement.intlTelInput('getNumber'));
where foo
is a placeholder for some function that depends on the result of the getNumber
method attached to the intlTelInput jQuery plugin, and domElement
is the intl-tel-input element associated with this object in arr
.
In the examples from the intl-tel-input project source page, unique element IDs are mostly used to select specific instances of the control on the page, however I cannot use any element IDs because there could be multiple instances of the widget on the page, leading to ID collisions.
Without explicitly using unique IDs, how can I "bind" an HTML element to a javascript object, as opposed to binding the javascript object to the HTML element?
Upvotes: 1