53

I have a list of outerItems. Inside each outerItem, I have a list of innerItems. They are dynamically sorted.

When mouse cursor points at one of innerItems, I have to show the popup window right above that innerItem element.

Popup div is body's child, because I do not want to have a separate popup for each of innerItems.

The way as I see it — on ng-mouseover I call the function that sets left/top properties to my absolutely positioned popup. So for each of innerItems I'd like to call jQuery .offset() method that gives me left/top values from the top-left corner of page.

So how can I get jQuery object of current scope element? Or, if I've chosen the wrong way

2 Answers 2

70

In controller:

function innerItem($scope, $element){
    var jQueryInnerItem = $($element); 
}
Sign up to request clarification or add additional context in comments.

13 Comments

you have chosen the wrong way. Dont EVER access $element in the controller. You need to wrap this as a Popup directive and then put in the pop-up's in your HTML.
It goes against angular's no-dom-manipulation-in-the-controller mantra. Keeps code decoupled, allows for easier testing, and keeps all dom manipulation code declarative and in the templates. That being said, sometimes you need the element. Browser autocompletes of fields, for example, fill the inputs but don't trigger ng_model updates. In those cases you sort of have to $(el).val() the input.
It's not ideal, but sometime unavoidable. Like if you're dealing with inner content delivered from a CMS.
Accessing elements in controller is completely OK if you have to deal with integrating Angular with the real world.
@hurshagrawal: I hear this mantra a lot, but none of its chanters have shown me how to write a controller for a Google Map, and add custom controls without manipulating the DOM. (Having the controller delegate to a service to do it doesn't count.) angular-google-maps doesn't feature the ability to add custom controls, possibly for this very reason. If you or any of your disciples can show me, post code here. Otherwise, I'll continue to assume your mantra is as applicable to the real world as any other dogma.
|
7

The better and correct solution is to have a directive. The scope is the same, whether in the controller of the directive or the main controller. Use $element to do DOM operations. The method defined in the directive controller is accessible in the main controller.

Example, finding a child element:

var app = angular.module('myapp', []);
app.directive("testDir", function () {
    function link(scope, element) { 

    }
    return {
        restrict: "AE", 
        link: link, 
        controller:function($scope,$element){
            $scope.name2 = 'this is second name';
            var barGridSection = $element.find('#barGridSection'); //helps to find the child element.
    }
    };
})

app.controller('mainController', function ($scope) {
$scope.name='this is first name'
});

2 Comments

the question is how to get html in dom. So how to get in controller string of html from some dom element by id?
i've voted this answer down, because it's not an answer for posted question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.