I have an angular app like this
Plunker
Javascript:
(function(angular, module){
module.controller("TestController", function($scope){
$scope.magicValue = 1;
});
module.directive("valueDisplay", function () {
return {
restrict: "A",
template: '<span>Iso Val: </span>{{ value }}<br/><span>Iso Change: </span><input data-ng-model="value" />',
replace: false,
scope: { },
link: function (scope, element, attrs) {
var pValKey = attrs.valueDisplay;
// Copy value from parent Scope.
scope.value = scope.$parent[pValKey];
scope.$parent.$watch(pValKey, function(newValue) {
if(angular.equals(newValue, scope.value)) {
// Values are the same take no action
return;
}
// Update Local Value
scope.value = newValue;
});
scope.$watch('value', function(newValue) {
if(angular.equals(newValue, scope.$parent[pValKey])) {
// Values are the same take no action
return;
}
// Update Parent Value
scope.$parent[pValKey] = newValue;
});
}
};
});
}(angular, angular.module("Test", [])));
HTML:
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js@*" data-semver="1.2.0-rc2" src=".2.0-rc.2/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="Test">
<div ng-controller="TestController">
<ol>
<li>
<span>Parent Val: </span>{{ magicValue }}<br/>
<span>Parent Change:</span><input data-ng-model="magicValue" />
</li>
<li data-value-display="magicValue"></li>
</ol>
</div>
</body>
</html>
Ok so This works and all but I'm wondering if there is not a better way of doing this 2 way binding that I have setup here?
Keep in mind that I want Isolated Scope & that I know I can define extra Attributes and use the '=' to have 2 way data binding between parent and isolated scope I'd like something like that but where the data gets passed in to the directives attribute like I have here.
I have an angular app like this
Plunker
Javascript:
(function(angular, module){
module.controller("TestController", function($scope){
$scope.magicValue = 1;
});
module.directive("valueDisplay", function () {
return {
restrict: "A",
template: '<span>Iso Val: </span>{{ value }}<br/><span>Iso Change: </span><input data-ng-model="value" />',
replace: false,
scope: { },
link: function (scope, element, attrs) {
var pValKey = attrs.valueDisplay;
// Copy value from parent Scope.
scope.value = scope.$parent[pValKey];
scope.$parent.$watch(pValKey, function(newValue) {
if(angular.equals(newValue, scope.value)) {
// Values are the same take no action
return;
}
// Update Local Value
scope.value = newValue;
});
scope.$watch('value', function(newValue) {
if(angular.equals(newValue, scope.$parent[pValKey])) {
// Values are the same take no action
return;
}
// Update Parent Value
scope.$parent[pValKey] = newValue;
});
}
};
});
}(angular, angular.module("Test", [])));
HTML:
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js@*" data-semver="1.2.0-rc2" src="http://code.angularjs/1.2.0-rc.2/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="Test">
<div ng-controller="TestController">
<ol>
<li>
<span>Parent Val: </span>{{ magicValue }}<br/>
<span>Parent Change:</span><input data-ng-model="magicValue" />
</li>
<li data-value-display="magicValue"></li>
</ol>
</div>
</body>
</html>
Ok so This works and all but I'm wondering if there is not a better way of doing this 2 way binding that I have setup here?
Keep in mind that I want Isolated Scope & that I know I can define extra Attributes and use the '=' to have 2 way data binding between parent and isolated scope I'd like something like that but where the data gets passed in to the directives attribute like I have here.
Share Improve this question asked Oct 28, 2013 at 9:48 DeMeNteDDeMeNteD 3854 silver badges11 bronze badges 1- 1 What is stopping you from using scope : {valueDisplay : '=valueDisplay'}? you don't have to set up the watches and the value is still in an attribute. It's also brittle to use $parent, since you can never be sure that the value is actually set in the parent. – Narretz Commented Oct 28, 2013 at 9:56
1 Answer
Reset to default 3You can do this much more tersely using your isolated scope.
Here is an updated plunker.
You can two-way bind the value of your directive with value: '=valueDisplay'
The =
tells angular you want two-way binding:
module.directive("valueDisplay", function () {
return {
restrict: "A",
template: '<span>Iso Val: </span>{{ value }}<br/><span>Iso Change: </span><input data-ng-model="value" />',
replace: false,
scope: { value: '=valueDisplay' },
link: function (scope, element, attrs) {
}
};
});