AngularJS - Packaging Directives

It seems that the isolated areas in the directives confuse me and I hope you can help me.

I tried to wrap a piece of code (which contains some custom directives) in a new directive to reduce code duplication. Obviously, I needed to specify some attributes of type ng-model in my new directive as a parameter in order to make the directive reusable. ng-model does not like expressions (at first I tried ng-model="{{myVariableWhichContainsDesiredNgModelString}}" ), and thus I ended up in this article: AngularJS - create a directive using ng-model ,

Despite the fact that the accepted answer works for simple setup, I edited the plunker from the accepted answer to check whether it will work with the nested directives: (in my application I need to wrap the directives from a third-party manufacturer, a library that I cannot edit) Plunker . In my code, each directive seems to generate its own scope and two-way data binding, using = in the scope definition does not seem to work as desired.

EDIT: Since it was not clear what I was asking, I edited Plunker above and rephrased the question: in Plunker, I have three input fields that must be associated with the same model — cost. This works at first, but as soon as I edit the third input field, it generates its own variable in an isolated area, rather than updating the initial value. Obviously, the third input field refers to the new variable from this point. How can I avoid this behavior and save the input associated with $scope.model.name ?

Observation : removing the isolated scope directive from the template makes everything work as expected ...

 template: '<div><my-input ng-model="myDirectiveVar"></my-input></div>', 

instead

 template: '<div><my-isolated-scope-directive><my-input ng-model="myDirectiveVar"></my-input></my-isolated-scope-directive></div>', 

Plunker

HTML:

 <!-- this binds to the model which i would like all my inputs to bind to.--> <input ng-model="name"> <!-- Example 1: This seems to generate a new modelvalue in the isolated-scope directive. Can I avoid this without modifying that directive?--> <my-isolated-scope-directive><my-input ng-model="name"></my-input></my-isolated-scope-directive> <!-- Example 2: This is what i would like my code to look like in the end: One directive which uses the code-snippet of Example 1 as template and passes some parameters into that template.--> <my-wrapper-directive my-directive-var="name"></my-wrapper-directive> 

directives:

my-input contains a modified input field:

 app.directive('myInput', function() { return { restrict: 'E', replace: true, require: 'ngModel', template: '<input class="some">', link: function($scope, elem, attr, ctrl) { console.debug($scope); } }; }) 

my-isolated-scope-directive is a placeholder directive with its own isolated scope for modeling behavior for nested directives:

 .directive('myIsolatedScopeDirective', function() { return { restrict: 'E', transclude: true, replace: true, scope: { something: '=' }, template: '<div ng-transclude></div>', link: function($scope, elem, attr, ctrl) { console.debug($scope); } }; }) 

my-wrapper-directive encapsulates both previous directives and accepts a parameter that should be used as the value of the ng model for the input field:

 .directive('myWrapperDirective', function() { return { restrict: 'E', transclude: false, replace: true, scope: { myDirectiveVar: '=' }, template: '<div><my-isolated-scope-directive><my-input ng-model="myDirectiveVar"></my-input></my-isolated-scope-directive></div>', link: function($scope, elem, attr, ctrl) { console.debug($scope); } }; }); 

Any suggestions and tips about what I am missing are appreciated. Can I somehow associate ng-model with an instance of a service without specifying my directive dependent on that service?

+5
source share
1 answer

I would not do it the way it is the old notation using regions ... I would use controllerAs and bindToController

script:

 var app = angular.module('plunker', []); app.controller('MainCtrl', function() { this.model = { name: 'World' }; this.name = "Felipe"; }); app.directive('myInput', function() { return { restrict: 'E', replace: true, // controllerAs: 'app', require: 'ngModel', template: '<input class="some">', controller: function(){ } }; }) .directive('myIsolatedScopeDirective', function() { return { restrict: 'E', transclude: true, controllerAs: 'app1', bindToController: { something: '=' }, template: '<div ng-transclude></div>', controller: function(){ } }; }) .directive('myWrapperDirective', function() { return { restrict: 'E', transclude: false, controllerAs: 'app2', bindToController: { myDirectiveVar: '=' }, template: '<div><my-isolated-scope-directive>'+ '<my-input ng-model="app2.myDirectiveVar"></my-input>'+ '</my-isolated-scope-directive></div>', controller: function(){ } }; }); 

index:

 <!doctype html> <html ng-app="plunker" > <head> <meta charset="utf-8"> <title>AngularJS Plunker</title> <link rel="stylesheet" href="style.css"> <script>document.write("<base href=\"" + document.location + "\" />");</script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script> <script src="app.js"></script> </head> <body ng-controller="MainCtrl as main"> This scope value <input ng-model="main.model.name"> <my-isolated-scope-directive> <my-input ng-model="main.model.name"></my-input> </my-isolated-scope-directive> <my-wrapper-directive my-directive-var="main.model.name"> </my-wrapper-directive> </body> </html> 

See the plunker: http://plnkr.co/edit/VD0wXO1jivQc3JvfQFTh?p=preview

UPDATE yes, a good point, so if you want to use controllerAs you need angular 1.2 at least, for bindToController you need angular 1.3

+2
source

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


All Articles