Question

following these great article link i have write my own directive to dinamically create a template for a window that have to be characterized by the nature of the data that will have to send, to be more clear my app have to send a text input, the directive creates a input area, rather then a checkbox in the case that have to send a boolean.
After succesfully obtain the directive i have found a problem in binding the contents of templates to send it back.
I have read the documentation of the directive, and i find the transclude value that maybe can help me, but i didn't have success in my attempt, i write the code below, like they ara in my app

HTML

<div id="notespace">
    <div id="userContainer" >
        <template-type content="additionalField">
                {{toBind}}
        </template-type>
        <button ng-click="addNote(toBind)">OK</button>
    </div>
</div>

JSfile of HTML controller page

var noteCtrl = function ($scope) {   
        $scope.additionalField=[{
             template:'text'
             }]

        for(var counter=0;counter<$scope.additionalField.length;counter++){
            var template;
            switch ($scope.additionaField[counter].template) {
                case 'text':
                    template = 'inputNote';
                    break;
                case 'otherTypeOfText':
                    template = 'areaNote';
                    break;
                case 'number':
                    template = 'inputNote';
                    break;                   
                case 'bool':
                    template = 'checkNote';
                    break;
                case 'file':
                    template = 'fileNote';
                    break;
            }
        }
    })
$scope.addNote=function(a) {
    alert(a);
}

JSfile for the DIRECTIVE

templateApp.directive('templateType',function($compile){
    var inputNote='<div><input type="text"/></div>';
    var areaNote='<div><textarea ></textarea></div>';
    var checkNote='<div><input type="checkbox" /></div>';
    var fileNote='<div >file</div>';

    var getTemplate=function(type){
        var template='';
        switch (type) {
            case 'inputNote':
                template = inputNote;
                break;
            case 'areaNote':
                template = areaNote;
                break;
            case 'checkNote':
                template = checkNote;
                break;
            case 'fileNote':
                template = fileNote;
                break;
        }
        return template;
    };
    var linker=function(scope,element,attrs){

        element.html(getTemplate(scope.content.template));
        $compile(element.contents())(scope);
    };
    return{
        restrict:"E",
        replace:true,
        transclude:true,
        link:linker,
        scope:{
            content:'='
        }
    };
});

to be extremelly clear the problem is that the addNote function's alert print nothing or undefined and not the content of the template like the inputArea one

Was it helpful?

Solution

If you want to display the value you sent inside the directive, just add the ng-transclude directive to the element in which you want to copy the interpolated value of the expression toBind.

app.directive('foobar', [function() {
    return {
        restrict: 'E',
        transclude: true,
        replace: true,
        template: '<div ng-transclude></div>',
        link: ...
    }
}])

Usage:

<foobar>{{someValueFromScope}}</foobar>

Result:

<div>someValueFromScope</div>

EDIT:

If I understood your problem now, you could do something like this:

<template-type content="additionalField" option="toBind"></template-type>

In directive:

var inputNote='<div><input type="text" ng-model="option"/></div>';

scope: {
    content: '=',
    option: '@'
}

Now when you change the content of the input it will be reflected in the option variable.

EDIT 2:

I got a working example: jsfiddle

I also corrected the code in the previous edit.

EDIT 3: When you change the value of options, the directive broadcasts an event optionsValueChanged to its parent scope (which happens to be the scope of the controller). The scope reacts to this event by updating the value of data.anotherValue. But it's not really the way these things should be handled, if you really need to use a value in more than one place then it's better to use a provider (value or service). It's not really relevant/useful to your question.

OTHER TIPS

In Html you should add controller something like this

<div id="notespace" ng-controller="noteCtrl">
    <div id="userContainer" >
        <template-type content="additionalField">
                {{toBind}}
        </template-type>
        <button ng-click="addNote(toBind)">CONFERMA</button>
    </div>
</div>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top