Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Required controllers in Directives #37

Closed
dainkaplan opened this issue Mar 25, 2015 · 4 comments
Closed

Required controllers in Directives #37

dainkaplan opened this issue Mar 25, 2015 · 4 comments
Milestone

Comments

@dainkaplan
Copy link
Contributor

Angular lets you specify a "require" attribute that lists out required controllers to inject into the directive (for example, see: http://stackoverflow.com/a/23033626/595033). How can we do that here?

In Angular you can require multiple controllers, and all of them get added as arguments to the link function, though in practice maybe only a couple at most are used.

Specifically I am trying to use the ngModel controller in a directive; I can define a class for it, but I can't wire it up that I see. Is there a way to do this today? I'm not trying to define a controller in the directive, just use one.

@ludovicc
Copy link
Collaborator

I have added the require attribute and a few other attributes on the Directive interface, can you give it a try?

Something like this should work, but I have not tested it.

  trait Directive2Ctrl extends js.Object {
    var bar: String = js.native
  }

  class Directive2 extends Directive {
    override type ControllerType = Directive2Ctrl

    override require = "^tabs"

    override def controller(ctrl: ControllerType, scope: ScopeType, elem: JQLite, attrs: Attributes): Unit = {
      ctrl.bar = "foo"
    }

    override def postLink(scope: ScopeType, element: JQLite, attrs: Attributes, ctrl: Directive2Ctrl): Unit = {
      element(0).textContent = ctrl.bar
    }
  }

@dainkaplan
Copy link
Contributor Author

Brilliant! I will check it out but your example might be conflating directives that define controllers and directives that require them. I think the controller function def is extraneous: https://docs.angularjs.org/guide/directive

@dainkaplan
Copy link
Contributor Author

Hello! It looks like this is close, but not quite! The generated JS code looks like the following:

  var ddo = {
    "template": s,
    "restrict": s$1,
    "require": (function(dimpl$3) {
      return (function() {
        return "ngModel"
      })
    })(dimpl),

I think inside createDirective you need to modify the code to emit either an array or a string instead of the function:

  private def createDirective(ct: c.Type, name: c.Tree) = {
    val module = Select(c.prefix.tree, TermName("self"))

    // assemble all defined directive attributes (ie 'template', 'restrict', ...)
    val atts = getDirectiveAttributes(ct).map( a => (a.name.toString,a)) map {
      case ("isolateScope",_)  => q"scope = dimpl.isolateScope"
      case ("preLink",_)       => q"link = dimpl.preLink _"
      case ("postLink",_)      => q"link = dimpl.postLink _"
      case ("controller",_)    => q"""controller = js.Array("$$scope","$$element","$$attrs",(dimpl.controller _):js.ThisFunction)"""
      case ("require",a)       => q"require = dimpl.${a.name}"
      case (_,a) if a.isGetter => q"${a.name} = dimpl.${a.name}"
      case (_,a)               => q"${a.name} = (dimpl.${a.name} _):js.Function"
    }

And, a pull request for it: #39

@jokade jokade added this to the v0.2 milestone May 7, 2015
@jokade
Copy link
Owner

jokade commented May 7, 2015

@dainkaplan can we close this issue?

@jokade jokade closed this as completed May 11, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants