Reputation: 1606
I just can't find a good source that explains to me how to manipulate DOM elements with angular:
How do I select specific elements on the page?
<span>This is a span txt1</span>
<span>This is a span txt2</span>
<span>This is a span txt3</span>
<span>This is a span txt4</span>
<p>This is a p txt 1</p>
<div class="aDiv">This is a div txt</div>
Exp: With jQuery, if we wanted to get the text from the clicked span, we could simple write:
$('span').click(function(){
var clickedSpanTxt = $(this).html();
console.log(clickedSpanTxt);
});
How do I do that in Angular?
I understand that using 'directives' is the right way to manipulate DOM and so I am trying:
var myApp = angular.module("myApp", []);
myApp.directive("drctv", function(){
return {
restrict: 'E',
scope: {},
link: function(scope, element, attrs){
var c = element('p');
c.addClass('box');
}
};
});
html:
<drctv>
<div class="txt">This is a div Txt</div>
<p>This is a p Txt</p>
<span>This is a span Txt </span>
</drctv>
How do I select only 'p' element here in 'drctv'?
Upvotes: 1
Views: 2453
Reputation: 3707
ng-click is the simpler solution for that, as long as I do not really understand what you want to do I will only try to explain how to perform the same thing as the one you have shown with jquery.
So, to display the content of the item which as been clicked, you can use ng-click directive and ask for the event object through the $event parameter, see https://docs.angularjs.org/api/ng/directive/ngClick
so here is the html:
<div ng-controller="foo">
<span ng-click="display($event)" >This is a span txt1</span>
<span ng-click="display($event)" >This is a span txt2</span>
<span ng-click="display($event)" >This is a span txt3</span>
<span ng-click="display($event)" >This is a span txt4</span>
<p>This is a p txt 1</p>
<div class="aDiv">This is a div txt</div>
</div>
and here is the javascript
var myApp = angular.module("myApp", []);
myApp.controller(['$scope', function($scope) {
$scope.display = function (event) {
console.log(event.srcElement.innerHtml);
//if you prefer having the angular wrapping around the element
var elt = angular.element(event.srcElement);
console.log(elt.html());
}
}]);
If you want to dig further in angular here is a simplification of what ng-click do
.directive('myNgClick', ['$parse', function ($parse) {
return {
link: function (scope, elt, attr) {
/*
Gets the function you have passed to ng-click directive, for us it is
display
Parse returns a function which has a context and extra params which
overrides the context
*/
var fn = $parse(attr['myNgClick']);
/*
here you bind on click event you can look at the documentation
https://docs.angularjs.org/api/ng/function/angular.element
*/
elt.on('click', function (event) {
//callback is here for the explanation
var callback = function () {
/*
Here fn will do the following, it will call the display function
and fill the arguments with the elements found in the scope (if
possible), the second argument will override the $event attribute in
the scope and provide the event element of the click
*/
fn(scope, {$event: event});
}
//$apply force angular to run a digest cycle in order to propagate the
//changes
scope.$apply(callback);
});
}
}
}]);
plunkr here: http://plnkr.co/edit/MI3qRtEkGSW7l6EsvZQV?p=preview if you want to test things
Upvotes: 0
Reputation: 1700
To Answer your first question, in Angular you can hook into click events with the build in directive ng-click. So each of your span elements would have an ng-click attribute that calls your click function:
<span ng-click="myHandler()">This is a span txt1</span>
<span ng-click="myHandler()">This is a span txt2</span>
<span ng-click="myHandler()">This is a span txt3</span>
<span ng-click="myHandler()">This is a span txt4</span>
However, that's not very nice, as there is a lot of repetition, so you'd probably move on to another Angular directive, ng-repeat to handle repeating your span elements. Now your html looks like this:
<span ng-repeat="elem in myCollection" ng-click="myHandler($index)">This is a span txt{{$index+1}}</span>
For the second part of your question, I could probably offer an 'Angular' way of doing things if we knew what it was you wanted to do with the 'p' element - otherwise you can still perform jQuery selections using jQuery lite that Angular provides (See Jamie Dixon's answer).
If you use Angular in the way it was intended to be used, you will likely find you have no need to use jQuery directly!
Upvotes: 1
Reputation: 691655
You should avoid DOM manipulation in the first place. AngularJS is an MVC framework. You get data from the model, not from the view. Your example would look like this in AngularJS:
controller:
// this, in reality, typically come from the backend
$scope.spans = [
{
text: 'this is a span'
},
{
text: 'this is a span'
},
{
text: 'this is a span'
}
];
$scope.clickSpan = function(span) {
console.log(span.text);
}
view:
<span ng=repeat="span in spans" ng-click="clickSpan(span)">{{ span.text }}</span>
Upvotes: 0
Reputation: 53991
Since element
is a jQuery-lite element (or a jQuery element if you've included the jQuery library in your app), you can use the find
method to get all the paragraphs inside : element.find('p')
Upvotes: 1