javascript - Angularjs directive with isolated scope needs clarification -
edit:
there functional example in plunker:
http://plnkr.co/edit/gfqgp0q3o9rjlalranps?p=preview
outer scope has $scope.name = 'donald'
all directives declared as:
<directive-name binding="name">
this multi-part question. im trying gain better understanding of isolated scopes has watch or binding outer scope variable.
with non-isolated scope directive works should:
// [works] .directive('noscopewithwatch', function(){ return { restrict: 'e', link: function(scope, lelement, attrs) { scope.$watch(attrs.binding, function(name){ lelement.text('hello ' + name); }); } }; }) // returns hello donald
the confusing part when try isolate scope , keep binding. im asking clarification on why of following examples work, while , others not.
if add scope isolation 'normal' binding fails:
// 1. [fails] .directive('scopewithwatch', function(){ return { restrict: 'e', link: function(scope, lelement, attrs) { scope.$watch(attrs.binding, function(name){ lelement.text('hello ' + name); }); }, scope: { // new content binding: '=' // new content } // new content }; }) // returns hello undefined
however, using binding variable in watch string makes work:
// 2. [works] .directive('scopewithwatchstring', function(){ return { restrict: 'e', link: function(scope, lelement, attrs) { scope.$watch('binding', function(b){ // new content lelement.text('hello ' + b); }); }, scope: { binding: '=' } }; }) // returns hello donald
while using binding variable object fails misribly:
// 3. [fails] .directive('scopewithwatchobject', function(){ return { restrict: 'e', link: function(scope, lelement, attrs) { scope.$watch(binding, function(b){ // new content lelement.text('hello ' + b); }); }, scope: { binding: '=' } }; }) // not work @ // console output - referenceerror: binding not defined
trying reference binding variable insinde isolated scope not work either, @ least not cause exception :
// 4. [fails] .directive('scopewithwatchscopeobject', function(){ return { restrict: 'e', link: function(scope, lelement, attrs) { scope.$watch(scope.binding, function(b){ // new content lelement.text('hello ' + b); }); }, scope: { binding: '=' } }; }) // returns hello undefined
it turns out using binding variable in mustaches in template works:
// 5. [works] .directive('scopewithtemplate', function(){ return { restrict: 'e', template: 'hello {{binding}}', // new content , linker removed scope: { binding: '=' } }; }) // returns hello donald
but trying use them mustaches in linker not.
// 6. [fails] .directive('scopewithwatchstringusingmustashes', function(){ return { restrict: 'e', link: function(scope, lelement, attrs) { // new content scope.$watch('binding', function(){ // new content lelement.text('hello {{binding}}'); // new content }); // new content }, // new content scope: { binding: '=' } }; }) // returns hello {{binding}}
here plunker:
http://plnkr.co/edit/gfqgp0q3o9rjlalranps?p=preview (im @ version 78, please fork if want use in answer.)
could please explain me why examples work while others not.
there simple answer this, applies examples here. angular documentation on $compile explains this, easy misunderstand. entire purpose of isolated scope create scope consumed directive declares it. in order so, new variable created stores value alias of parent scope.
there 3 major definition types: @
, =
, &
@ or @attr - bind local scope property value of dom attribute. result string since dom attributes strings.
= or =attr - set bi-directional binding between local scope property , parent scope property of name defined via value of attr attribute.
& or &attr - provides way execute expression in context of parent scope.
the difference between @
, =
bi-directional support. =
definition still return string result.
so, have, in order, is:
- isolated scope not provide access attrs collection, has access it's own isolated scope items. not work, there no attrs object in scope.
- works intended,
binding='name'
matchedbinding: '='
,'binding'
accessable alias in isolated scope. - fails, because attrs strings, not javascript objects.
- fails,
the 'isolate' scope differs normal scope in not prototypically inherit parent scope. useful when creating reusable components, should not accidentally read or modify data in parent scope.
- works, same reason 2. bindings matched. templates handled
$compile
automatically. - fails, because
lelement.text
that, text. using expression within text assignment requires additional manual compile step before text sent dom, else{{}}
expression treated plain text.
Comments
Post a Comment