0

Angular: Can anyone explain why transcluded content in a directive can only update objects on the scope - not variables directly on the scope. Is it just because the object and functions are ref type in javascript and why does the binding work one way and ... why does the binding break after the update inside the transcluded content (see plunker samples)

-Plunker sample - variable on scope vs object on scope

Working -Plunker sample - variable on scope

Buchholt
  • 13
  • 3

1 Answers1

0

Transcluded content can also update parent's scope properties

Transcluded content is like any other content, therefore if you followed the dot.rule you'll be able to update the parent scope properties you want. Always follow the dot.rule and refactor your logic to make sure everything is done in the angular way.

Directive scope types

Directives in angular prior to 2.0 version accept several types of scopes, the scope can be true, which creates a new one and inherits parent's properties; false, which does not create a new scope, but still inherit parent's properties; or {} which is known as an isolated scope, this creates a new scope with zero properties, it keeps only the properties you declare.

One-Way vs Two-Way data binding

Angular uses both, one-way and two-way data binding. For example, two-way data binding occurs when you use the ng-model directive, whenever you update the model, the view will reflect those changes and viceversa. On the other hand, one-way data binding occurs when you use the interpolation {{some.property}}


The two-way data binding should not break if you are using the dot.rule. That's how prototypical inheritance works after all.

Check out this Pen to illustrate everything said in this answer.

Community
  • 1
  • 1
Manuel Ro
  • 206
  • 3
  • 10
  • I know it works if I bind to an object like $scope.person = { name: "" } - but why not to an var like $scope.personname = "" ? – Buchholt Apr 09 '16 at 19:18
  • Because of prototypical inheritance. Angular is based on JavaScript, and this behavior is due to JavaScript itself. Usually is better to rely on services, values and constants to handle that kind of shared information between scopes. – Manuel Ro Apr 09 '16 at 19:19
  • Although you can also access parent's properties directly and bind to them using `$parent.myProperty`. – Manuel Ro Apr 09 '16 at 19:27
  • I know that ... as said by Kyle Simpson: "... JavaScript isn't "inheriting" by copying DOWN the chain, but rather delegating UP the chain ..." – Buchholt Apr 09 '16 at 19:45
  • It seems that adding a scope to the transcluder breaks the chain - if it's an variable on the scope -< event the $parent cannot help at this – Buchholt Apr 09 '16 at 19:46
  • Using the $parent works as long as the transclude directive does not have a scope on it – Buchholt Apr 09 '16 at 19:50
  • With scope on the transcluder function it does not work - but without it works fine! -> modification of your codepen: https://codepen.io/buchholt/pen/zqROJj – Buchholt Apr 09 '16 at 20:15
  • What angular logic am I missing! – Buchholt Apr 09 '16 at 20:16
  • Got it: I have to use $parent.$parent if I introduce a scope on my transclude directive. Than you [Manuelro](http://stackoverflow.com/users/3663518/manuelro) for your comment with the $parent ... got me on track! Updated with working [plunker sample](https://plnkr.co/edit/UfMppw?p=preview) – Buchholt Apr 10 '16 at 07:00
  • Sure. You're welcome! However, you should take into consideration that `$parent` is not intended be used in this way. I think you may go better with services, values and constants, those can be shared by controllers and adhere to Angular principles of doing things. – Manuel Ro Apr 10 '16 at 18:45