Jeanluca Scaljeri
Jeanluca Scaljeri

Reputation: 29109

AngularJs: create directive

I've a question about a directive I want to write. Here is the jsfiddle This is the HTML

<div ng-controller="TestCtrl">
    <mydir base="{{absolute}}">
        <div>{{path1}}</div>
        <div>{{path2}}</div>
    </mydir>
</div>

The directive, called 'mydir', will need the value of the base attribute and all the path values (there can be any number of paths defined). I don't want to inject values from the controller directly into the directive scope (they need to be independent). I have 3 questions about this (checkout the jsfiddle too!)

1) although the code works as it is now, there is an error: "TypeError: Object # has no method 'setAttribute'". Any suggestions what is wrong?

2) in the directive scope.base is 'undefined' instead of '/base/'. Can this be fixed.

3) How can I make a list of all the path values in the directive ?

Upvotes: 0

Views: 106

Answers (3)

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40296

You need to set an isolate scope that declares the base attribute for this directive:

scope: {
    base: "@"
}

This solves (2).

Problem (1) is caused from the replace: true in cooperation with the scope above, because it creates a comment node to contain the repeated <div>s.

For (3), add paths: "=" to scope and, of ocurse, pass them from the parent controller as an array.

See forked fiddle: http://jsfiddle.net/swYAZ/1/

Upvotes: 2

lastboy
lastboy

Reputation: 576

If you want to make a robust directive to be able to replace the data to its content (3) You can pass a reference as an attribute and display the data accordingly.

See this article, look for wrapper widget.

Upvotes: 1

m.e.conroy
m.e.conroy

Reputation: 3538

You're creating an new scope in your directive by setting scope: true what you want to do is:

app.directive('mydir', function ($compile, $rootScope) {
    return {
        replace: true,
        restrict: 'E',
        template: '<div ng-repeat="p in paths"> {{base}}{{p}}/{{$index}}</div>',
        scope: {
            base : '='
        },

        link: function (scope, iElement, iAttrs) {
            scope.paths = ['p1', 'p2'] ;
        }
    }
});

This will setup a bi-directional binding between your directive's local scope and the parent's scope. If the value changes in the parent controller it will change in the directive as well.

http://jsfiddle.net/4LAjf/8/

Upvotes: 1

Related Questions