Ross R
Ross R

Reputation: 9403

How to access scope of transcluded elements

I have a directive element. Within it I have a form that I want to set some of the directive's scope properties. Like so:

 <trans-dir>
    <form role='form' class='form-inline'>
      <div class='form-group'>
        Select Value:
        <label>
          <input type='radio' ng-model='data' value='Val1'>Val1
        </label>
        <label>
          <input type='radio' ng-model='data' value='Val2'>Val2
        </label>
      </div>
    </form>
  </trans-dir>

I'm baffled by how the scopes work (even though I've read a bunch about it):

So, I want the form to set the directive controller's scope. If it were the same scope, that would be fine. If it were the transcluded scope (08) I could then access it. No problem. But it's yet another scope - 05. I can traverse to it using trasnscludedScope.$$prevSibling, but I don't really know what's going on and I don't know if that is legit and deterministic.

More detailed code at: http://plnkr.co/edit/z70R6W?p=preview

So my questions:

  1. How do I access the FORM scope?
  2. What's going on with these scopes? Why is my form scope different from my transcluded scope?
  3. Bonus: Where are scopes 6 & 7?? (In my real project I have tons of scopes I don't know the source of, and batarang always says they have no model, which can't always be true.)

Upvotes: 0

Views: 1000

Answers (2)

heavi5ide
heavi5ide

Reputation: 1609

If you use ng-transclude, you don't need to call transcludeFn manually. When you call it manually, you're creating the #8 scope. It is called automatically by ng-transclude to create #5. So, the form scope is the transcluded scope, just not the one that you're creating manually (that's why it doesn't have the $watch set on it). I'm not sure if there's a way to access the auto-generated transclude scope created by ng-transclude. You could, however, not use ng-transclude, and instead make your manual call to transcludeFn (like you are already doing) and manually append the cloned element to your DOM.

Upvotes: 1

Stuart Nelson
Stuart Nelson

Reputation: 4202

Your directives will inherit their parent scope if one isn't declared, so removing that will simplify this.

Also, one of those scope gotchas about angular:

If you set a "plain variable" in a child that inherits scope from a parent, it WON'T propagate back up — it will have its own variable instantiated and updated.

$scope.plainString = "derp";
// child will inherit this, but if it gets set in child it will be
// instantiated there as its own variable and won't affect the parent

However, if there is a query as part of that, the variable will be changed in the parent.

$scope.objToQuery = {
    value: "derp"
};
// child will inherit this, and when it gets changed there
// e.g. ng-model="objToQuery.value"
// it WILL be changed in the parent

This object that you "query" must exist in the parent scope.

Check out this modified plunkr: http://plnkr.co/edit/SftstP7L2OJnfLka8OLd?p=preview

Does this help?

Upvotes: 1

Related Questions