I have a directive that will use ng-model
to expose its value.
The question is that this directive have internal components that will also mess the scope, so I need to isolate its scope, but still preserve ng-model
bind to outside world.
How would I achieve this?
This is the directive:
angular.module('app', []).directive('myDirective', function() {
return {
restrict: 'E',
require: 'ngModel',
link: function(scope, element, attr, ngModel) {
// do stuff using ngModel controller
},
replace: true,
template: '<div><input ng-model="userInput" /></div>'
};
});
<my-directive ng-model="prop"></my-directive>
As you can see, the directive must expose prop
as its value, but should not expose userInput
in the parent scope, defined in <input ng-model="userInput"/>
.
How would I be able to make only prop
available in the parent scope?
Normally, ngModelController is meant to be used with directives that do not create a new scope. The only way I've found to get it to work with an isolate scope is to use the same name in the isolate scope:
scope: { prop: '=ngModel' } // must use 'prop' here!
For more discussion on this, see my SO answer: https://stackoverflow.com/a/14792601/215945
You can also have the directive create a new scope using scope: true
. If you do this, then prop
would need to be an object property, not a primitive: e.g., ng-model='someObj.prop'
. For more on this approach, see the first fiddle of this https://stackoverflow.com/a/13060961/215945
This would still allow you to create your own (new) properties on the new directive child scope, without affecting the parent scope. Well, you need to be aware of how scope prototypal inheritance works somewhat -- objects defined on the parent scope will be visible and changeable in the directive child scope. Primitives defined on the parent scope will be visible, but if you try to change the value of a parent primitive you'll end up creating a child property that hides/shadows the parent property of the same name. (Lots more info about prototypal inheritance can be found here.)