The correct method is to handle the Angular scope instead of $ parent. $ Parent

I read several articles and did not find an example that solves my problem.

I understand that:

  • ng-if and ng-repeat create selection areas.
  • Using $parent.someProperty bad.
  • Using $parent.$parent.someProperty would be an abomination.

So, with this template markup, how can I properly link the controller to update the controller property?

Markup:
(note the nested ng-if and ng-repeat , creating the form $parent.$parent )

 <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 build the directive and / or markup correctly to gain access to settings.someProperty in the controller? Or is there something completely different that I need to do?

Explanation
There seems to be some kind of confusion about what I'm trying to do. someProperty is available in the directive - this works fine. Note that I am trying to assign values ​​to someProperty controller someProperty from a directive (using ng-model)

Update
I revised the code above to a known working code and added jsFiddle . Note that it works, but uses $parent.$parent in the template. This is a problem that I need to understand how to solve it.

+5
source share
4 answers

You can pass the settings to a directive which, in my opinion, is the easiest / most direct / clean way to do this.

Angular correctly evaluates settings as MyCtrl.settings , and then passes it to the highlighting area of ​​the setting directive. Inside the directive you have a two-way binding on settings , so you can update the settings from there.

After changing your example, go to settings in the directive in the markup :

<setting settings="settings" item="item" />

Then in JavaScript replace this for the template:

template: '<input type="radio" ng-model="settings.someProperty" ng-value="item" name="mySetting" />',

Here's a working fiddle .

+2
source

EDIT

I completely rewrite my answer based on your violin and a simpler two-way approach to data binding. Note to future readers that the first couple of comments no longer apply 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 property of the parent controller and the directive. With this approach, you must pass an attribute to each individual property of the parent area and bind it in the selection area.

+1
source

One option when hierarchical relationships and data transfer is complicated is to separate the parent / child relationship and just have a data exchange service.

I saw some great explanations about this, like passing state through services , sample code . You can also adapt this idea for use with a common caching service, such as Angular $ cacheFactory or, more complex, this library: angular-cache .

0
source

Why don’t you just add the "someproperty" parameter to go to the settings directive = for example:

 myApp.directive('setting', function() { return { restrict: 'E', template: '<input type="radio" ng-model="myProperty" value="{{item}}" />', scope: { settings: '=', item: '=', myProperty: '=' } }; }); 

And in your markup:

 <label ng-repeat="item in repeatingItems"> {{item}} <setting item="item" myProperty="settings.someProperty" /> </label> 
0
source

Source: https://habr.com/ru/post/1241548/


All Articles