I've been reading a few articles, and haven't found the example that solves my issue.
My understanding is that:
ng-if
and ng-repeat
create isolate scopes.$parent.someProperty
is bad.$parent.$parent.someProperty
would be an abomination.So, with the given template markup, how can I properly bind the the controller so that the controller property updates?
Markup:
(note the nested ng-if
and ng-repeat
, creating a sort of $parent.$parent
situation)
<div ng-app="MyApp" ng-controller="MyCtrl">
<div ng-if="showOnCondition">
<label ng-repeat="item in repeatingItems">
{{item}}
<setting item="item" />
</label>
</div>
{{checkSetting()}}
</div>
JavaScript
var myApp = angular.module('MyApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.settings = {
someProperty: '',
anotherProperty: 'Hello'
}
$scope.repeatingItems = [
'One',
'Two',
'Three'
];
$scope.showOnCondition = true;
$scope.checkSetting = function() {
// When calling checkSettings(), I would like to access the value of someProperty here
return $scope.settings;
}
});
myApp.directive('setting', function() {
return {
restrict: 'E',
require: '^myCtrl',
// HOW DO I SOLVE THIS?
// $parent.$parent is bad.
template: '<input type="radio" ng-model="$parent.$parent.settings.someProperty" name="mySetting" value="{{item}}" />',
scope: {
settings: '=',
item: '='
}
};
});
Given the above example, how to I properly construct the directive and / or markup in order to access settings.someProperty
in the controller? Or is there something entirely different I need to be doing?
Clarification
There seems to be some confusion around what I'm trying to do. The someProperty
is available in the directive - that is working fine. Please note I'm trying to assign values to the controller's someProperty
property from within the directive (using ng-model)
Update
I've revised the code above to known, working code, plus added a jsFiddle.
Note that it works, but it uses $parent.$parent
in the template. This is the problem I need to understand how to solve.
You can pass settings through to the directive, which I think is the simplest / most direct / cleanest way to do this.
Angular properly evaluates settings
as MyCtrl.settings
, then passes it through to the isolate scope of the setting
directive. Inside the directive, you have two-way binding on settings
, so you can update settings from there.
Modifying your example, pass in settings
into the directive in the Markup:
<setting settings="settings" item="item" />
Then in the JavaScript, swap out this for the template:
template: '<input type="radio" ng-model="settings.someProperty" ng-value="item" name="mySetting" />',
Here's a working fiddle.
EDIT
I'm rewriting my answer completely, based on your fiddle and a simpler two-way data-binding approach. Note to future readers that the first couple of comments are no longer relevant to this updated answer.
HTML
<div ng-app="MyApp" ng-controller="MyCtrl">
<div ng-if="showOnCondition">
<label ng-repeat="item in repeatingItems">
{{item}}
<setting test="settings.someProperty" item="item" />
</label>
</div>
{{checkSetting()}}
</div>
JS
var myApp = angular.module('MyApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.settings = {
someProperty: true,
anotherProperty: 'Hello'
}
$scope.repeatingItems = [
'One',
'Two',
'Three'
];
$scope.showOnCondition = true;
$scope.checkSetting = function() {
// When calling checkSettings(), I would like to access the value of someProperty here
return $scope.settings;
}
});
myApp.directive('setting', function() {
return {
restrict: 'E',
replace: true,
template: '<input type="radio" ng-model="test" name="mySetting" value="{{item}}" />',
scope: {
test: '=',
item: '='
}
};
});
This provides two-way data-binding between the parent controller property and the directive. With this approach, you would pass in each individual parent scope property to an attribute, and bind it in your isolate scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With