I have have a directive inside an ng-repeater that should set a scope property. Please see the fiddle here: http://jsfiddle.net/paos/CSbRB/
The problem is that the scope property is given as an attribute value like this:
<button ng-update1="inputdata.title">click me</button>
The directive is supposed to set the scope property inputdata.title to some string. This does not work:
app.directive('ngUpdate1', function() {
return function(scope, element, attrs) {
element.bind('click', function() {
scope.$apply(function() {
scope[ attrs.ngUpdate1 ] = "Button 1";
});
});
};
});
However, assigning directly works:
scope["inputdata"]["title"] = "Button 1";
Can you please tell me how I can set a scope property with . notation in its name from a directive?
PS: The reason the fiddle is using a repeater is because it makes the directives be in child scopes. When they are in a child scope, you can't write to scope properties that are primitives. That's why I need an object property with "." in the name. See the long explanation here: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
Thank you
$parse will solve your problem.
<button ng-update1="inputdata.title">
app.directive('ngUpdate1', function($parse) {
return function(scope, element, attrs) {
var model = $parse(attrs.ngUpdate1);
console.log(model(scope)); // logs "test"
element.bind('click', function() {
model.assign(scope, "Button 1");
scope.$apply();
});
};
});
Fiddle
Whenever a directive does not use an isolate scope and you specify a scope property using an attribute, and you want to modify the value, use $parse
.
If you don't need to modify the value, you can use $eval
instead:
console.log(scope.$eval(attrs.ngUpdate1));
Not sure what overall objective is but one way is to create 2 attributes, one for the target object and the other for the property of that object:
<button ng-update1 obj="inputdata" prop="title">
app.directive('ngUpdate1', function() {
return function(scope, element, attrs) {
element.bind('click', function() {
scope.$apply(function() {
scope[ attrs.obj ][attrs.prop] = "Button 1";
});
});
};
});
DEMO:http://jsfiddle.net/CSbRB/9/
Alternatively using existing format you could split()
value of your current ng-update1
attribute and use result array for object and property in notation
element.bind('click', function() {
var target=attrs.ngUpdate1.split('.');
scope.$apply(function() {
scope[ target[0] ][target[1]] = "Button 1";
});
});
DEMO with both approaches: http://jsfiddle.net/CSbRB/10/
One more approach where you create an isolated scope in directive and can pass in the reference to inputdata
object and pull property name from attribute(same markup as second version):
app.directive('ngUpdate3', function () {
return {
scope: {
targetObject: '=obj'
},
link: function (scope, element, attrs) {
element.bind('click', function () {
scope.$apply(function () {
scope.targetObject[attrs.prop]='Button 3';
});
});
}
}
});
http://jsfiddle.net/CSbRB/11/
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