3

I would like to send JSON object with function template from app.controller to another directive controller. I decided to send this variable as attribute of inner directive's element. The problem is that object which is inside $attr.valueAtt in my directive controller is "[object Object]" and I can't get it:

My code:

var value = (
  [{
     functionLabel:'Fun', 
     functionTemplate: function(param1,param2){
       alert(param1);
     }, 
     functionParams: ['PARAM1','PARAM2']
  }]);

Then I add it in controller as attribute of directive element:

angular.element(document.getElementById('space-for-modals'))
         .append($compile("<modal-dialog visible='true' data-backdrop='static' valueAtt='"+value+"'></<modal-dialog>")($scope));

And try to get "value" in my directive controller:

 $scope.functions=  $attrs.valueAtt;

But in $scope.functions is only "[object Object]". Is there any way to send function template from one to another controller to call it later?

1
  • Could you add whitespace / newlines / linebreaks in your code examples please? Commented May 13, 2015 at 14:32

2 Answers 2

3

The problem is that when you do valueAtt='"+value+"', JavaScript converts value to a string - which is "[object Object]". You need to store your object in the scope and then reference it by name in the HTML attribute. Something like this:

  var scope2 = scope.$new();
  scope2.foo = [{
     label:'Fun', 
     fn: function(param1, param2){
       alert("Callback function says: " + param1)
     }, 
     params: ['PARAM1', 'PARAM2']
  }];

  angular.element(document.getElementById('space-for-modals'))
     .append($compile("<modal-dialog visible='true' data-backdrop='static' value-att='foo'>Modal dialog</<modal-dialog>")(scope2));

Then in your modal dialog link function you can dereference value-attr to get foo:

link: function(scope, elem, attrs) {
  scope.functions = scope[attrs.valueAtt];
}

And in your dialog controller, you can access the functions member. Note that this won't be ready until after the link function has been called, so you need to use a watch:

  $scope.$watch('functions', function(functions) {
    if (functions == null)
      return;
    var ft = functions[0];
    ft.fn.apply(null, ft.params);
  });

Here's a demo.

I must say, it's a bit odd to be compiling HTML like this - why not just use a template in your directive declaration? If it's because you want to put the content at another level of your DOM, consider using a service to communicate with it (basically, you set a field on a shared singleton object). Also, you could use an isolate scope to avoid binding the attribute yourself.

A service could store a callback function that would be triggered by your controller:

.service('modalService', [function() {
  var proxy = function(message) {
    proxy.callback(message);
  };
  proxy.callback = function() {};
  return proxy;
}])

If you inject that into both your dialog and trigger controllers, you can communicate between them. The modal dialog should replace the callback with its own function. Here's another demo.

Sign up to request clarification or add additional context in comments.

3 Comments

probably would be a good idea to actually show how to set the obj on the scope
1. I'm the new one with Angular so maybe I'm wrong but I suppose that also here var scope2 = scope.$new(); is some kind static and when I'will get two request in the same time to show modal window data from one scope2.foo can be eclipsed by second request - or should I dynamically create separated scope3 scope4 scope so on for every modal window ? 2. Idea with isolated scope looks quite interesting but can I create controllers dynamically as in example .controller('NaomiController', ['$scope', function($scope) ? Or it have to be hardcoded ?
1. scope2 = scope.$new() was just an example because I don't know where you're currently getting your scope from. You can do this however you like. Since the dialog controller is watching that array, if you replace it with another one (e.g. duplicate and append an item to it) then the dialog will update. 2. Well, it has to be hard-coded. But you can put whatever you like into the scope, such as functions as illustrated above. I really think a service would be better for this. I'll add another demo.
0

Okej I suspeced that's conversion problem but I actually can't store "value " in static variable in major $scope because I would like to use it to call modal-window with generic functionality which depends from functions stored in "value" this is why I decided to give "value" as attribute. Is there any other option to save "value" with functions in view or give it directly to directive controller ?

Comments

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.