Created
April 1, 2015 13:01
-
-
Save bennadel/d55de41cc985a48647fc to your computer and use it in GitHub Desktop.
Mutating Isolate Scope References In AngularJS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html ng-app="Demo"> | |
<head> | |
<meta charset="utf-8" /> | |
<title> | |
Mutating Isolate Scope References In AngularJS | |
</title> | |
</head> | |
<body ng-controller="AppController"> | |
<h1> | |
Mutating Isolate Scope References In AngularJS | |
</h1> | |
<p> | |
You have {{ friends.length }} friends! | |
<!-- If you are friends with Kim, that's extra awesome. --> | |
<span ng-if="includesKim">That's awesome!</span> | |
</p> | |
<!-- | |
Pass the friends collection into the LIST component directive which gives it a | |
two-way data binding to the collection. Also pass-in a method that can be used | |
to mutate said collection. | |
-- | |
NOTE: The argument name being used in the addFriend() method - "item" - must | |
also be used in the isolate-scope component directive, otherwise, the value will | |
not be passed-in properly. | |
--> | |
<div bn-list="friends" add-item="addFriend( item )"></div> | |
<!-- This is the template for the component directive. --> | |
<script type="text/ng-template" id="list.htm"> | |
<ul> | |
<li ng-repeat="item in collection"> | |
{{ item }} | |
</li> | |
</ul> | |
</script> | |
<!-- Load scripts. --> | |
<script type="text/javascript" src="../../vendor/angularjs/angular-1.3.15.min.js"></script> | |
<script type="text/javascript"> | |
// Create an application module for our demo. | |
var app = angular.module( "Demo", [] ); | |
// -------------------------------------------------- // | |
// -------------------------------------------------- // | |
// I control the root of the application. | |
app.controller( | |
"AppController", | |
function( $scope ) { | |
// Start out with THREE items in the friends collection. | |
$scope.friends = [ "Sarah", "Joanna", "Heather" ]; | |
// If we are friends with Kim, that's extra cool. Of course, looking at | |
// the local collection, we know that this won't be true at the time the | |
// Controller is instantiated. | |
$scope.includesKim = ( $scope.friends.indexOf( "Kim" ) !== -1 ); | |
// --- | |
// PUBLIC METHODS. | |
// --- | |
// I push a new friend onto the collection. | |
$scope.addFriend = function( newFriend ) { | |
// Validate action. | |
if ( ! newFriend ) { | |
throw( new Error( "InvalidArgument" ) ); | |
} | |
$scope.friends.push( newFriend ); | |
// Now that we have a new friend, there may be a chance that we can | |
// turn on the friend-specific flag. | |
$scope.includesKim = ( $scope.friends.indexOf( "Kim" ) !== -1 ); | |
}; | |
} | |
); | |
// -------------------------------------------------- // | |
// -------------------------------------------------- // | |
// I provide a component directive for listing out items. | |
app.directive( | |
"bnList", | |
function() { | |
// Return the directive configuration object. | |
// -- | |
// NOTE: We are creating an isolate scope with a two-way data binding to | |
// whatever reference is passed into the bn-list attribute. We are also | |
// expecting a method that can be used to mutate the isolated scope | |
// reference for said collection. | |
return({ | |
link: link, | |
scope: { | |
collection: "=bnList", | |
mutateCollection: "&addItem" | |
}, | |
templateUrl: "list.htm" | |
}); | |
// I bind the JavaScript events to the local scope. | |
function link( scope, element, attributes ) { | |
// When we use the mutateCollection method to alter the bound | |
// collection, we have to use the "locals" object to bind a local | |
// value to the arguments list defined in the template. Meaning, | |
// the following key, "item", has to be the one used in the template | |
// that consumes this component directive. | |
scope.mutateCollection({ | |
item: "Kim" | |
}); | |
} | |
} | |
); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html ng-app="Demo"> | |
<head> | |
<meta charset="utf-8" /> | |
<title> | |
Mutating Isolate Scope References In AngularJS | |
</title> | |
</head> | |
<body ng-controller="AppController"> | |
<h1> | |
Mutating Isolate Scope References In AngularJS | |
</h1> | |
<p> | |
You have {{ friends.length }} friends! | |
<!-- If you are friends with Kim, that's extra awesome. --> | |
<span ng-if="includesKim">That's awesome!</span> | |
</p> | |
<!-- | |
Pass the friends collection into the LIST component directive which gives it a | |
two-way data binding to the collection. | |
--> | |
<div bn-list="friends"></div> | |
<!-- This is the template for the component directive. --> | |
<script type="text/ng-template" id="list.htm"> | |
<ul> | |
<li ng-repeat="item in collection"> | |
{{ item }} | |
</li> | |
</ul> | |
</script> | |
<!-- Load scripts. --> | |
<script type="text/javascript" src="../../vendor/angularjs/angular-1.3.15.min.js"></script> | |
<script type="text/javascript"> | |
// Create an application module for our demo. | |
var app = angular.module( "Demo", [] ); | |
// -------------------------------------------------- // | |
// -------------------------------------------------- // | |
// I control the root of the application. | |
app.controller( | |
"AppController", | |
function( $scope ) { | |
// Start out with THREE items in the friends collection. | |
$scope.friends = [ "Sarah", "Joanna", "Heather" ]; | |
// If we are friends with Kim, that's extra cool. Of course, looking at | |
// the local collection, we know that this won't be true when at the time | |
// the Controller is instantiated. | |
$scope.includesKim = ( $scope.friends.indexOf( "Kim" ) !== -1 ); | |
} | |
); | |
// -------------------------------------------------- // | |
// -------------------------------------------------- // | |
// I provide a component directive for listing out items. | |
app.directive( | |
"bnList", | |
function() { | |
// Return the directive configuration object. | |
// -- | |
// NOTE: We are creating an isolate scope with a two-way data binding to | |
// whatever reference is passed into the bn-list attribute. | |
return({ | |
link: link, | |
scope: { | |
collection: "=bnList" | |
}, | |
templateUrl: "list.htm" | |
}); | |
// I bind the JavaScript events to the local scope. | |
function link( scope, element, attributes ) { | |
// CAUTION: Because the isolate scope provides for a two-way data | |
// binding to passed-in scope reference, this collection can now be | |
// mutated directly by the isolate directive. This is NOT a violation | |
// of the documentation in any way; but, it is likely a violation of | |
// good practices since the "owner" of the data is not aware that | |
// these changes are being made. | |
scope.collection.push( "Kim" ); | |
} | |
} | |
); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment